OC Setter 方法底层实现

397 阅读1分钟

以前一直以为OC中的set方法在底层统一调用了objc_setProperty方法,后来在研究OC生成的C++代码过程中,发现有的set方法使用了指针偏移的方式直接访问实例变量,有的却是使用objc_setProperty

@interface SetterTest : NSObject

@property (nonatomic, strong) NSString *a;

@property (nonatomic, copy) NSString *b;

@property (atomic, strong) NSString *c;

@property (nonatomic, strong) NSString *d;

@end

@implementation SetterTest

@end

image.png 观察上面的代码发现,确实是使用了两种方式。由于代码生成的不同,所以猜测是编译器来控制的,在LLVM源码中搜索objc_setProperty发现了以下代码:

image.png 通过名字就可以发现,这是用来生成set方法的,代码中通过判断PropertyImplStrategy strategy来生成不同的set方法,PropertyImplStrategy实现如下:

image.png 那么接下去只需要知道PropertyImplStrategy是如何初始化的,就能知道编译器是怎么区分属性的。 关键代码 1:如果是Copy 那么必然使用SetProperty,至于Get 则根据是否是原子性判断。

  // If we have a copy property, we always have to use setProperty.
  // If the property is atomic we need to use getProperty, but in
  // the nonatomic case we can just use expression.

image.png 关键代码 2:如果不是Copy,则根据原子性来判断,当使用原子性时,则会使用SetProperty

image.png