Weak
weak 表示指向,但不持有该对象,其实修饰的对象引用计数不会增加。
__weak与Weak 基本相同,前者修饰变量(variable),后者用于修饰属性(property)。__weak 主要防止block中的循环引用。
weak 实现的三步骤:
- object_InitWeak (初始化新的weak指针指向对象的地址)
- store_weak (更新指针的指向,创建弱引用表)
- weak_register_no_lock(通过哈希运算拿到弱应用表)
Strong
表示指向并持有该对象,起修饰的对象引用计数+1,该对象只要引用计数不为0,就不会被销毁,当然也可以设置为nil强行销毁。
__weak typeof (self)weakSelf = self;
self.block =^{
// 1
weakSelf.p = "123";
__strong typeof (self)strongSelf = weakSelf;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//2
strongSelf.p = "321";
});
};
self.block();
在一个block内,为了调用(1)当前对象p,给self进行弱引用__weak 处理。
在block中,有一个GCD的延时操作,里边想调用对象p, 按照执行顺序,当block执行结束,作用域会销毁。那么weak 机会被释放->nil。 strongSelf修饰weakSelf,在block内引用计数+1,出了作用域block销毁(延时任务执行完毕后, strongSelf 会被回收)。
Assign
主要修饰基本数据类型,如NSinteger、CGFloat,这些数值主要存在于栈中。
如果用assign修饰对象, 对象被释放后,指针的地址依然存在,会造成“野指针”,在堆上容易造成奔溃。而栈上的内存系统会自动处理。
nontamic 与atomic 区别
atomic 修饰的对象会保证setter和getter方法的完整性,任何线程访问题都可以得到一个完整的的初始化后的对象。因为要保证完整性,所以比较耗时。相对于nonatomic较为安全。(非绝对安全,多线程资源抢夺也会得到不一样的值, 也得使用@synchronized)
nontamic 修饰的对象不会保证setter和getter方法的完整性,任何线程访问题不一定得到一个完整的的初始化后的对象,正因为如此,他比atomic的速度快。