美文网首页
第四更 内存(__weak、 __strong、 __unsaf

第四更 内存(__weak、 __strong、 __unsaf

作者: RunningTeemo | 来源:发表于2018-04-26 20:34 被阅读0次

1、循环引用的时候用__weak与__strong是常见的手段
strong 修饰的属性会在赋值时调用被指向对象的 retain 方法,导致其引用计数加1 。
weak 则不会。

__weak typeof(self) weakSelf = self;  
self.block = ^{  
       [weakSelf print];  
}

上述方法可以解决循环引用的问题,但是当对象先与block释放的时候,block也就会被释放,这样的话self就指向了nil。等block回来时,其实在向一个nil发消息。

__weak typeof(self) weakSelf = self;  
self.block = ^{  
      __strong typeof(weakSelf) strongSelf = weakSelf;  
      [strongSelf print];  
};

__strong在block的内部临时把引用计数+1了,strongSelf是block内部的一个局部变量,变量的作用域仅限于局部代码,而程序一旦跳出作用域,strongSelf就会被释放,这个临时产生的“循环引用”就会被自动打破。

2、__unsafe__unretained
__unsafe_unretained:和__weak 一样,唯一的区别便是,对象即使被销毁,指针也不会自动置空, 此时指针指向的是一个无用的野地址。如果使用此指针,程序会抛出 BAD_ACCESS 的异常。

id __unsafe_unretained obj = [[NSMutableArray alloc]init];  
[obj addObject:@"obj"]; 

这里先不管编译器的警告,继续执行,在第二条语句就会崩溃,分析:
附有__unsafe_unretained修饰符的变量同附有__weak修饰符的变量一样,因为自己生成并持有的对象不能继续为自己持有,所以生成的对象会立即被释放。也就是说在执行完init方法以后,obj指针所指向的内存就已经释放掉了,可是obj指针并没有像附加__weak的指针那样,将指针自动置为nil,它依然指向原来的地址,可是这块地址的内存已经被系统回收了,再访问就是非法的,也就是野指针,再执行后面的addObject方法自然会出错了。
也就是说上面的代码,把__unsafe_unretained换成__weak就不会崩溃,因为obj会自动制置为nil。对nil发送消息是不会有问题的。
https://blog.csdn.net/chenyong05314/article/details/55657388 这里形象的对比了strong、weak、__unsafe__unretained的内存区别。
3、____autoreleasing

id __strong obj0;  
id __weak obj1;  
id __autoreleasing obj2;  
  
// __strong,__weak,__autoreleasing可以保证附有这些修饰符的自动变量初始化为nil  
  
// 上面源码和下面效果等同  
  
id __strong obj0 = nil;  
id __weak obj1 = nil;  
id __autoreleasing obj2 = nil;  
//在文件中引入以下声明即可使用这两个函数  
    extern void _objc_autoreleasePoolPrint();//打印注册到自动释放池中的对象  
    extern uintptr_t _objc_rootRetainCount(id obj);//获取对象的引用计数  

https://blog.csdn.net/junjun150013652/article/details/53149145这篇文章里面做了详细的解释,但是我还是不太明白,留着等后面在理解
看的有点晕,但是我理解就是把用__autoreleasing修饰,就是把变量放到@autoreleasepool中,把引用计数-1

相关文章

网友评论

      本文标题:第四更 内存(__weak、 __strong、 __unsaf

      本文链接:https://www.haomeiwen.com/subject/kegmlftx.html