参考资料:
《招聘一个靠谱的 iOS》—参考答案(上)
WEAK 和 UNOWNED
iOS 开发之 Copy/MutableCopy |
@property的本质是什么?@property后面有哪些关键词?
@property用来声明属性,他相当于 实例变量 + setter、getter方法。
@property后面的关键词有:
- 用来声明原子性atomic与非原子性nonatomic;
- 用来表示内存特性的strong、assign、copy;
- 用来设置读取特性的readwrite、readonly;
- 以及用来重新定义serter、getter方法名的如:@property(nonatomic, strong, getter=p_initBy, setter=setP_initBy:)NSString *initBy;
什么时候使用weak?weak与assign、unowned的区别?
当会出现循环引用的时候,往往通过设置一端为weak来避免,比方说UITableView的delegate、datasource属性都是用weak修饰;已经进行过强引用没必要再进行强引用一次的时候,比方说通过xib/storyboard添加的控件关联到代码中的@IBOutlet属性。
weak用来修饰对象类型,是弱引用,assign用来修饰基本数据类型; weak表示一种非拥有关系(nonowning relationship),为weak属性设置新值时,设置方法既不保留新值,也不释放旧值;但weak修饰的对象在被释放后,指针地址会被置为nil;如果在对象类型中使用assign修饰,当对象释放后assign类型的指针不会变为nil,就会导致野指针,再是访问就会导致崩溃。
@property (nonatomic, weak) id weakPoint;
@property (nonatomic, assign) id assignPoint;
- (void)setWeakPoint:(id)weakPoint {
_weakPoint = weakPoint;
// objc_setAssociatedObject(self, "weakPoint", weakPoint, OBJC_ASSOCIATION_ASSIGN);
// [weakPoint cyl_runAtDealloc:^{
// _weakPoint = nil;
// }];
}
- (void)setAssignPoint:(id)assignPoint {
_assignPoint = assignPoint;
}
runtime是如何实现weak变量自动设置为nil的?
runtime对注册的类会进行布局,对于weak对象会放入一个hash表中。用weak指向对象的内存地址作为key,当对象的引用计数为0的时候会进行dealloc,假如 weak 指向的对象内存地址是a,那么就会以a为键, 在这个 weak 表中搜索,找到所有以a为键的 weak 对象,从而设置为 nil。
@protocol 和 category 中如何使用 @property
Swift中为什么不明确写出属性的内存属性关键词?Swift为什么不写atomic关键词?
Swift中大部分情况下不写属性关键词,是因为使用了默认的关键词。引用类型默认是用到 了strong,值类型默认是assign,weak仍需要开发者手动设置;Swift中所有的property都是nonatomic;读取属性通过var、let、private、public来控制。