iOS中的@synthesize 和 @dynamic详解

1,952 阅读2分钟

这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战

@synthesize

synthesize意思是合成,有两个功能:

  1. 给属性生成setter / getter 方法
  2. 给属性起个别名

但是通常情况下用不到synthesize,因为我们定义属性时使用了@roperty,这个会自动会帮我们加上synthesize

//比如使用roperty`声明了属性
@property (nonamic,copy) NSString *name;
//就等同于还设置synthesize
@synthesize name = _name;

所以使用property后,属性会只有getter/setter方法,还可以直接通过下滑线

那么什么情况下要使用synthesize:

  1. 需要给属性起个别名
  2. 手动添加了 setter/getter 方法
  3. 实现了带有peoperty属性的protocol

给属性起个别名

@interface Persion ()
@property (nonatomic, copy) NSString *hobby;
@end

@implementation Persion
//给属性起个别名
@synthesize hobby = _newHobby;

- (instancetype)init {
    if (self = [super init]) {
        self->_newHobby = @"hello";
        self.hobby = @"hello2";
        NSLog(@"hobby:%@ _newHobby:%@",self.hobby, self->_newHobby);
    }
    return self;
}

@end

打印结果:hobby:hello2 _newHobby:hello2

上面例子我们通过@synthesize hobby = _newHobby;设置了别名

然后通过给别名赋值再取值验证了别名_newHobbyself.hobby是同一个属性

手动添加了setter / getter方法

手动添加了setter / getter 方法后,系统就不会自动创建成员变量了,这个时候如果需要使用成员变量则要手动添加@synthesize来生成成员变量。

如下实例:

image-20211120020023317

当自己实现属性hobby的setter、getter方法后,就无法通过成员变量_hobby来赋值了。

image-20211120020210005

当使用@synthesize后,就可以调用到对应的成员变量了。

值得注意的是:

如果属性是可读可写,但我们只重写了setter、getter方法中的一个时,系统会自动合成剩下的方法和成员变量

image-20211120020604303

实现了带有peoperty属性的protocol

比如有个协议:

@protocol PersionProtocol <NSObject>

@property (nonatomic, copy) NSString *name;

@end

然后Student准守了协议

@interface Student : Persion<PersionProtocol>
@property (nonatomic, copy) NSString *teacher;
@end

然后在student.m文件如果使用成员变量就报错

image-20211120021511975

然后添加@synthesize后就可以了

image-20211120021613275

@dynamic

dynamic 是什么意思呢?翻了翻我破旧的英汉词典,dynamic是”动态的“意思

那在iOS中什么意思,意思就是这个属性的setter、getter方法不用系统帮我生成了。

这里我们验证下是不是使用了@dyanmic就真的不会生成对应getter、setter方法

PS:我是不是闲的

image-20211120225459939

看,当我们使用了@dynamic后,当使用点语法赋值时,就会报找不到setHobby:

此时有个小问题浮现在我的脑海

使用了@dynamic后,系统会自动给生成带下划线的成员变量吗?

我们来验证下:

image-20211120230352015

可以看到使用@dynamic后,带下划线的成员变量也不给创建了