block-循环引用

在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;
时间: 2024-10-06 03:06:56

block-循环引用的相关文章

block循环引用的简单说明

- (void)viewDidLoad {     [super viewDidLoad];     // 如果我们不对block进行copy操作, 那么block存在于栈区, 栈区的block块不会对引用的对象进行持有     // 如果我们对block进行了copy操作, 那么block就存在于堆区, block块就会对引用的对象进行持有          Student *student = [[Student alloc] init];     // 如何解决循环引用问题     //

和block循环引用说再见

to be block? or to be delegate? 这是一个钻石恒久远的问题.个人在编码中暂时没有发现两者不能通用的地方,习惯上更偏向于block,没有什么很深刻的原因,只是认为block回调写起来更便捷,直接在上下文中写block回调使得代码结构更清晰,可读性更强.而delegate还需要申明protocol接口,设置代理对象,回调方法与上下文环境不能很好契合,维护起来没有block方便.另外初学者很容易会被忘记设置代理对象坑- 然而惯用block是有代价的,最大的风险就是循环引用

关于block 循环引用 weakSelf

什么是block? 代码块:{}里的东西 block可以想id一样装到array里,dictionary里...但是不能对他发送消息. nsdictionary 里有一个方法:enumerateKeysAndObjectUsingBlock:^(id key,id value,BOOL *stop) 这个方法遍历dictionary里的东西,直到*stop = YES为止. block 里的代码对于主线程里的变量什么的都是可读的.除非主线程里的变量加上__block 例如:__block BOO

ios block 循环引用

无意中看到有人在咨询block循环引用如何解决的问题:记录下来,方便童鞋们参考 ios开发中,开了ARC模式,系统自动管理内存,如果程序中用到了block就要注意循环引用带来的内存泄露问题了 这几天遇到一个问题,正常页面dismiss的时候是要调用dealloc方法的,但是我的程序就是不调用,研究了好久终于找到了问题出在哪里了 起初的代码如下: - (void)getMyrelatedShops { [self.loadTimer invalidate]; self.loadTimer = [N

iOS Block循环引用

前言 本篇文章精讲iOS开发中使用Block时一定要注意内存管理问题,很容易造成循环引用.本篇文章的目标是帮助大家快速掌握使用block的技巧. 我相信大家都觉得使用block给开发带来了多大的便利,但是有很多开发者对block内存管理掌握得不够好,导致经常出现循环引用的问题.对于新手来说,出现循环引用时,是很难去查找的,因此通过Leaks不一定能检测出来,更重要的还是要靠自己的分析来推断出来. 声景一:Controller之间block传值 现在,我们声明两个控制器类,一个叫ViewContr

【少年,放松~】出现block循环引用的三种情况和处理办法

刚入职在看已经上线的项目,其中用到block进行快捷回调的做法很常用,但是Xcode都给给以了如下[循环引用]的警告(如下)的情况,结合网络上的查找和自己的理解,进行总结如下. // Capturing 'self' strongly in this block is likely to lead to a retain cycle 出现这种情况的原因主要是:因为block的特性,声明block的对象都会以copy的形式持有block,而block对于它内部的对象也会进行强引用,从而导致了循环引

ios之block循环引用

在 iOS 4.2 时,苹果推出了 ARC 的内存管理机制.这是一种编译期的内存管理方式,在编译时,编译器会判断 Cocoa 对象的使用状况,并适当的加上 retain 和 release,使得对象的内存被合理的管理.所以,ARC 和 MRC 在本质上是一样的,都是通过引用计数的内存管理方式. 然而 ARC 并不是万能的,有时为了程序能够正常运行,会隐式的持有或复制对象,如果不加以注意,便会造成内存泄露!今天就列举几个在 ARC 下容易产生内存泄露的点,和各位童鞋一起分享下. block 系列

Block循环引用,强引用方法引起的循环引用,CenterX CenterY 不生效的问题

相信大家都用过CenterX 和 CenterY吧,这2个属性确实非常方便,但是有些时候会发现突然设置了CenterX CenterY不好使了,不居中了,一头雾水.这种情况 我建议第一时间去看看设置CenterX CenterY之前有没有设置size 也就是 宽和高.如果在设置宽高之前就设置了CenterX CenterY 肯定是不生效的,原因不用多说了吧,如果是这种情况,将先设置一下size就好了. 上一篇文章提到了block里面用了self从而导致了 循环引用,控制器释放不了,有些朋友知道应

Block循环引用问题

根控制器没办法销毁,除非程序退出 从一个控制器跳到另外一个控制器,调用该控制器的pop方法才会销毁该控制器 self是一个强指针 在block中使用self时要注意循环引用的问题 最好将当前block中的self 强引用换成弱引用 如下图:

iOS Block循环引用精讲

前言 循环引用就是当self 拥有一个block的时候,在block 又调用self的方法.形成你中有我,我中有你,谁都无法将谁释放的困局.又或者解决方法简而言之就一句话的事情:__weak typeof (self) weakSelf = self; 本篇文章精讲iOS开发中使用Block时一定要注意内存管理问题,很容易造成循环引用.本篇文章的目标是帮助大家快速掌握使用block的技巧. 我相信大家都觉得使用block给开发带来了多大的便利,但是有很多开发者对block内存管理掌握得不够好,导