我们开始~
1.先了解一下@property 以及 @synthesize之间的区别和联系,说到@property 以及 @synthesize,我们就不得不提到iOS中 成员变量和属性 之间的区别和联系了。
iOS5.0之后 @property声明的属性默认会生成一个_类型的成员变量,同时也会生成setter/getter方法。
以前的写法是这样的
@interface ViewController ()
{
// 1.声明成员变量NSString *name;
}
//2.在用@property
@property(nonatomic, copy) NSString *name;
@end
@implementation ViewController
//3.最后在@implementation中用synthesize生成set方法
@synthesize name;
@end
在没有更改之前,属性的正常写法需要 成员变量 + @property + @synthesize 成员变量 三个步骤。
如果是粗心或者忘记写@synthesize 只写了成员变量 + @property
编译时会报警告:Auto synthesized property 'name' will use synthesized instance variable '_name', not existing instance variable 'name''
苹果爸爸将默认编译器从GCC转换为LLVM(low level virtual machine)之后就节省了我们的书写代码量。
更换为LLVM之后,编译器在编译过程中发现没有新的实例变量后,就会生成一个下划线开头的实例变量。因此现在我们不必在声明一个实例变量(注意:==是不必要,不是不可以==)你要是想知道个所以然写上也是可以滴~ @property声明的属性不仅仅默认给我们生成一个_类型的成员变量,同时也会生成setter/getter方法。在.m文件中,编译器也会自动的生成一个成员变量_name。
那么在.m文件中可以直接的使用_name成员变量,也可以通过属性self.name.都是一样的。注意这里的self.name其实是调用的name属性的setter/getter方法。(注在=号左边就是setter 在=号右边就是getter)
如果我们再最新的代码中声明一个成员变量,如下代码所示,那么我们只是声明了一个成员变量,而且不是以_ 开头, 并没有setter/getter方法。所以访问成员变量时,可以直接访问name,也可以像C++一样用self->name来访问,但绝对不能用self.name来访问。
@interface MyViewController :UIViewController
{
NSString *name;
}@end
从Xcode4.4以后,即iOS的@property已经独揽了@synthesize的功能主要有三个作用:
1.生成了成员变量get/set方法的声明
2.生成了私有的带下划线的的成员变量因此子类不可以直接访问,但是可以通过get/set方法访问。那么如果想让定义的成员变量让子类直接访问那么只能在.h文件中定义成员变量了,因为它默认是@protected
3.生成了get/set方法的实现
值得注意的是:
如果已经手动实现了get和set方法(两个都实现)的话Xcode不会再自动生成带有下划线的私有成员变量了
因为xCode自动生成成员变量的目的就是为了根据成员变量而生成get/set方法的,但是如果get和set方法缺一个的话都会生成带下划线的变量
@property 以及 @synthesize之间的联系与区别。同时,我们提到了self.xx和_xx的一点区别,其中self.xx是调用的xx属性的get/set方法,而_xx则只是使用成员变量_xx,并不会调用get/set方法。两者的更深层次的区别在于,通过存取方法访问比直接访问多做了一些其他的事情(例如内存管理,复制值等),例如如果属性在@property中属性的修饰符有retain,那么当使用self.xx的时候相应的属性的引用计数器由于生成了setter方法而进行加1操作,此时的retaincount为2。