在ARC机制下,app的内存管理由操作系统进行管理,不须要程序猿手动的管理内存,方便了开发.虽然,自己主动释放内存非常方便。可是并不是绝对安全,绝对不会产生内存泄露。
大部分导致iOS对象无法按预期释放的一个无形杀手是——循环引用。
循环引用能够简单理解为A引用了B,而B又引用了A,两方都同一时候保持对方的一个强引用。导致不论什么时候引用计数都不为0,始终无法释放。
以下我们介绍下block代码块,引起的循环引用以及解决的方法
block在copy时都会对block内部用到的对象进行强引用。第一种easy引起循环引用的一般表现为。某个类将block作为自己的属性变量,然后该类在block的方法体里面又使用了该类本身。简单说就是self.MyBlock = ^(Type var){[self dosomething]; 或者self.otherVar = XXX;或者_otherVar = …}, 造成了self 拥有一个block的时候,在block 又调用self的方法。block的这样的循环引用会被编译器捕捉到并及时提醒。
举比例如以下(People类):
我们能够看出在block的实现内部又使用了People类(self)的name属性。这个时候,编译器提醒给出了相关的警告.
解决方法:
通过使用_weak声明一个取代self的新变量取代原先的self,命名为weakSelf。通过这样的方式告诉block,不要在block内部对self进行强制强引用.
这样的循环引用的事例图为:
另外一种情况为:比如self 有一个button ,而你有要 调用 button的某个东西设置.[self.button ^{ }]因为某些原因,你又要在这个block里调用self的其它控件,比如self.textField.text = @”text”;就造成了讯混引用。
(即:控制器中有一个控件,在这个控件中又訪问了控制器的其它控件).比如AlertController中的Action对象訪问AlertController的textField对象.
为了进行演示的事例:首先我们定义了一个UIAlertController的子类(AlertController),并实现它的dealloc方法
- (void)dealloc{
NSLog(@"alertController dealloc");
}
在主控制器中创建AlertController,并实现点击确认的方法(获取其上的文本框内容信息)
点击确认后,打印例如以下
我们发如今销毁AlertController的时候,AlertController并没有释放,导致了内存的泄露.
改动为例如以下方式,点击确认后结果为:
能够看出,对象得到释放.
没有改动之前的事例图为:
解决循环引用后
解决方法
简而言之就一句话的事情:
__weak typeof (self) weakSelf = self;
手机扫一扫
移动阅读更方便
你可能感兴趣的文章