本文主要是解决什么属性和实例变量的区别,什么时候使用属性和实例变量,@synthesize的作用又是什么?
首先我们要先区分属性、实例变量和成员变量
属性是以@property开头的变量声明,@property开头的变量声明既可以在头文件中声明,也可以在实现文件中声明。
1、@property在不同的文件中声明会有什么区别了?
2、@property声明,系统做了什么?
3、为什么经常我们会看到在头文件中声明了@property之后,在实现文件中经常会@synthesize, @synthesize做了什么?
4、访问属性声明有多少种方式?属性对应的实例变量是什么?
成员变量和实例变量:
@interface MyClass: NSObject
{
int count;
id data;
NSString *name;
}
括号中为类成员变量, 成员变量 = 实例变量 + 基本数据类型变量
实例变量是一个类的实例,如NSString *name,id data(这个我自己不太确定,但按逻辑觉得应该是的,id很像指针,那这么说我更是不敢确定了,现在我连id是什么都不是太清楚),基本数据类型指int、float这种基本的数据类型。
成员变量在头文件和在实现文件中声明有什么区别?
首先我们分析@property的作用:
1、@propety在.h文件中声明,作用:
头文件:
@interface 类名
@property 类型 *属性名;
@end
等同于
头文件:
@interface 类名
{
类型 * _属性名;(本身存在或生成与属性对应的成员变量)
}
属性的getter方法声明;
属性的setter方法声明;
@end
实现文件:
@implement 类名
属性getter方法的实现;
属性setter方法的实现;
@end
语言描述:1、@property为属性名生成了对应的实例变量(我推测这个实例变量是私有的)@property在头文件中声明了setter和getter方法,和在实现文件中实现了setter方法和getter方法
问题:1、是不是@property生成的实例变量都是私有的?是生成的私有的。2、@property有公有和私有之分吗?应用没有。3、如果属性生成的实例变量是私有的,那么property的两种访问方式 实例.属性名 和[实例 get属性]实质上都是调用的[实例 get属性]?我猜是的。OC中点的表达式是表示调用getter方法(文章http://www.lxway.com/482926291.htm说的,写的不错),那另一个疑问来了,如果我在覆盖setter和getter方法中,使用.方法,会不会存在循环调用的问题呢?具体逻辑不明而厉,最好不要这么用。
2、@propety在.m文件中声明,作用:
实现文件:
@interface 类名
@property 类型 *属性名;
@end
等同于
实现文件:
@interface 类名
{
类型 * _属性名;(生成与属性对应的成员变量)
}
//不知道这里有没有getter和setter方法的声明,我猜是有的
@end
@implement 类名
属性getter方法的实现;
属性setter方法的实现;
@end
在实现文件中声明的属性是不能被访问到,原因,我的推测:因为我们在导入文件的时候都是导入.h文件(不知道能不能导入.m文件,反正我在导入.m文件之后,编译链接出现了奇葩问题:linker command failed with exit code 1 (use -v to see invocation), ld: 4 duplicate symbols for architecture x86_64),当然在其他文件中就不能访问到在.m文件中声明的属性了。
3、@synthesize的作用,为什么在实际的测试中不用@synthesize系统也会自动实现声明的方法,而网上说@synthesize的作用就是用来实现声明的方法的?
@synthesize实现了属性声明的访问方法。
在Xcode4.5及以后的版本中,可以省略@synthesize,编译器会自动帮你加上get和set的实现方法,并且默认会去访问“_属性名”这个成员变量,如果找不到"_属性名"这个成员变量,会自动生成一个叫做"_属性名"的私有成员变量。(这段话,可以具体参考 简述http://www.jianshu.com/p/bcf734db475c,这篇文章里讲的不错)
这段话,我有以下看法:
1、@property声明情况下,属性所对应的实例变量(属性所对应的实例变量可以使用@synthesize改变对应关系),首先会去成员变量里找,如果没有才会自动生成
2、@systhesize以前主要是用来实现声明的方法的,现在不用@synthesize系统一样会帮你实现声明方法的
3、@systhesize的语法:
现在我只遇到两种,第一种是@synthesize 属性名, 第二种是@synthesize 属性名 = 实例变量,这两种语法我都有些疑惑,暂时我是这样理解的(实际测试也是符合我这种理解的),第一种@synthesize属性名,其对应的实例变量是属性名,第二种属性对应的实例变量就是等于符号右边的实例变量。
关于@property和@synthesize的解释大致都解释清楚了,总结一下:@property声明分为两种情况:头文件和实现文件,头文件会自动声明方法,实现文件声明会不会自动生成声明方法不得而知,但是我猜至少外部是不能访问的。系统会为@property找对应的成员变量,没有对应的成员变量就会生成对应的成员变量,然后自动生成实现方法。暂时我知道的synthesize语句主要可以来将属性和成员变量对应起来。关于属性的访问主要有两种方式 类实例.属性名和[实例 属性],我的推测是类实例.属性名这种形式的访问本质上就是[实例 属性]这种访问形式。
下面让我们看一下成员变量的声明,成员变量的声明可以在头文件和普通文件中:好像有public、private和protected,具体使用是否与C++中的变量权限一致有待研究。