IOS-OC-@synthesize 的作用

iOS 6 之后 LLVM 编译器引入property autosynthesis,即属性自动合成。换句话说,就是编译器会为每个 @property 添加 @synthesize ,如以下形式:

@synthesize propertyName = _propertyName;

这行代码会创造一个带下划线前缀的实例变量名,同时使用这个属性生成getter 和 setter 方法。
使用@synthesize 只有一个目的——给实例变量起个别名,或者说为同一个变量添加两个名字。
如果要阻止自动合成,记得使用 @dynamic。经典的使用场景是你知道已经在某处实现了getter/setter 方法,而编译器不知道的情况。

此处我的理解是为了防止编译器使用自动合成生成新的setter/getter 会覆盖已经存在的旧的 setter/getter。

自动合成没有任何内存的含义,所以它根本没有连接到ARC。
如果你已经手动实现了 setter/getter方法,或着对 只读对象 实现了getter方法,那么自动合成不会产生任何影响。如果你在手动实现需要一个变量,只需声明它就可以了,不需要添加@synthesize来添加一个别名(尽管可以)。
还有一种情形需要使用 @synthesize ,就是当在 protocol 中声明并实现属性时。协议中声明的属性不会自动生成setter和getter,[UIApplicationDelegate window] 就是个典型的例子。
情形1:不使用@synthesize,可以使用自动生成的带下划线的实例变量名
情形2:使用@synthesize为属性添加带下划线的别名,与不使用@synthesize相同
@synthesize 声明的属性=变量。意思是,将属性的setter,getter方法,作用于这个变量。@synthesize还有一个作用,就是可以指定与属性对应的实例变量,例如我可以这样写@synthesize age = myAge;,那这样子的话我们去调用的时候self.age其实是操作的实例变量myAge,而不是_age了。
情形3:使用@synthesize为属性添加任意别名,此时使用自动生成的实例变量名将报错,只能使用指定的别名。

注意

1 属性的setter方法和getter方法是不能同时进行重写的,这是因为,一旦你同时重写了这两个方法,那么系统就不会帮你生成这个成员变量了,所以会报错,如果真的就想非要重写这个属性的setter和getter方法的话,就要手动生成成员变量,然后就可以重写了。或者是用

@synthesize:
@synthesize age = myAge;
 
- (void)setAge:(NSString *)age {
    myAge = age;
}
 
- (NSString *)age {
    return myAge;
}

2 在getter方法中最后返回return _age;而不是return self.age, 这是因为点语法实际上是对setter和getter方法的调用,如果在getter方法中调用return self.age的话,就会循环调用。
3 在重写属性的setter方法的时候我们一般都是这样写:

- (void)setInfoArr:(NSArray *)infoArr {
    _infoArr = infoArr;
    _infoArr = @[@"我是数组"];
}

我们需要在setter方法中加上这句_infoArr = infoArr;,我们在重写setter方法的时候将新值infoArr 赋值给属性变量_infoArr 以便我们在外面调用。
4 当.h文件中属性为readonly,.m文件中可以不用@synthesize 这个关键字,初始化的方式有下面几种
例如:

@property (nonatomic,strong,readonly) UILabel *placeHolderLabel;
- (void)setUpPlaceHolderLabel {
    _placeHolderLabel = [[UILabel alloc] init];
    _placeHolderLabel.textColor = [self.class defaultPlaceholderColor];
    _placeHolderLabel.numberOfLines = 0;
    _placeHolderLabel.userInteractionEnabled = NO;
    _placeHolderLabel.font  = self.font;
}
- (UILabel *)placeHolderLabel {
    UILabel *label = objc_getAssociatedObject(self, @selector(placeHolderLabel));
    if (!label) {
        label = [[UILabel alloc] init];
        label.textColor = [self.class defaultPlaceholderColor];
        label.numberOfLines = 0;
        label.userInteractionEnabled = NO;
        label.font  = self.font;
                objc_setAssociatedObject(self, @selector(placeHolderLabel), label, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        [self updatePlaceholderLabel];
    }
    return label;
}
@property (nonatomic,strong,readwrite) UILabel *placeHolderLabel;

总结
1.@synthesize 的作用:是为属性添加一个实例变量名,或者说别名。同时会为该属性生成 setter/getter 方法。
2.禁止@synthesize:如果某属性已经在某处实现了自己的 setter/getter ,可以使用 @dynamic 来阻止 @synthesize 自动生成新的 setter/getter 覆盖。
3.内存管理:@synthesize 和 ARC 无关。
4.使用:一般情况下无需对属性添加 @synthesize ,但一些特殊情形仍然需要,例如protocol中声明的属性
iOS协议里面可以定义成员变量和属性吗?(刚刚)

你可能感兴趣的:(IOS-OC-@synthesize 的作用)