Lmsgsendnilself

Uninhibited Soul, Free Craziness

Synthesize

| Comments

what

关键字@synthesize的作用是对成员变量及其getter和setter的合成。如果不写,默认为@syntheszie var = _var;

how

对于@synthesize,如果开发者没有实现setter和getter方法时,编译器会自动合成这两个方法,如果代码中了,就会用代码实现的。
而对于另一个关键字@dynamic,则必须要求开发者代码实现setter和getter方法,不然在程序运行,如果调用到self.var = someVar或者someVar = self.var时,会导致崩溃。

when

对编译器不会自动合成(autosynthesize)的场景更准确来说有如下几种情况:

  • 代码中实现了setter和getter

  • 对于只读(readonly)属性,代码实现了getter

  • 使用@dynamic而不是@synthesize,

  • 在协议 @protocol 中声明的属性

  • 在 category 中定义的属性,是肯定不会自动生成的,因此如果想实现category添加属性的效果,要使用objc_setAssociateObject和objc_getAssociateObject方法实现setter和getter。

  • 在子类中重载的父类中的属性,则必须使用@synthesize来手动合成相应的成员变量。

rule

  • 默认不写的情况为@synthesize name = name; 此时的成员变量为name。若name存在,则不再生成; 若name不存在,则会生成该成员变量。
  • 如果指定了成员变量名称,如@synthesize name = customName, 如果成员变量customName不存在,则会生成成员变量_customName

  • 如果是 @synthesize name; 如果没有成员变量name,则会生成成员变量name

note:若出现下面这种情况

1
2
3
4
5
6
7
8
9
10
@interface ViewController (){

    NSString *_name;
}

@implementation ViewController

@synthesize name;

@end

需要注意的是,此时@synthesize 合成的成员变量为name,并不是name,self.name访问的是成员变量name,一句话总结就是name和name是两个不同的成员变量。这种情况下如果用kvc时, [obj valueForKey:@"name"]找的是成员变量name的值,而[obj valueForKey:@"_name"]找的是成员变量_name的值。当然正常规范的代码肯定不能这样写,这不是给人添乱吗。

Comments