一篇文章让你看懂IOS中的block为何再也不需要WeakSelf弱引用
前言: 最近都在折腾Sagit架框的内存释放的问题,所以对这一块有些心得。 对于新手,学到的文章都在教你用:typeof(self) __weak weakSelf = self。 对于老手,可能早习惯了到处了WeakSelf了。 这次,就来学学,如何不用WeakSelf。 1:从引用计数器开始: 这里先设计一个TableBlock类: @interface BlockTable : NSObject typedef void (^AddCellBlock)(); @property (nonatomic,copy)AddCellBlock addCell;@end 先这么简单,一个Bloc 在iOS开发中,Block是一种强大的闭包特性,它允许我们将代码块当作对象处理。然而,由于Block会捕获并保留其内部引用的对象,这可能导致意外的循环引用问题,特别是当Block内部引用了`self`这样的强引用时。本文将探讨如何在iOS中使用Block而无需依赖`weakSelf`弱引用技巧。 我们需要理解引用计数的概念。Objective-C中的对象通过引用计数来管理内存,当对象的引用计数为0时,该对象会被自动释放。Block在声明时会捕获其所在作用域内的对象,这会导致Block本身持有这些对象的强引用,从而可能形成循环引用。 在文章的示例中,创建了一个名为`BlockTable`的类,它包含一个类型为`AddCellBlock`的属性。当我们给`addCell`属性赋值一个Block时,Block会捕获`BlockTable`实例,导致引用计数增加。当Block内部不直接引用`self`时,Block和`BlockTable`之间没有形成循环引用,因此对象能够正常释放。 然而,当Block内部引用了`self`,如在`reloadData`方法中调用`addCell`,Block与`BlockTable`之间就会形成循环引用,因为Block持有`BlockTable`,而`BlockTable`的`addCell`属性又持有Block。这种情况下,即使设置了`addCell`为`nil`,引用计数仍然不会降为0,对象无法被正确释放。 为了解决这个问题,开发者通常会在Block内部使用`weakSelf`弱引用来避免循环引用。但是,文章提出了一种不同寻常的方法:在设置`addCell`属性时,先将Block转化为弱引用,然后再赋值给`_addCell`。这样做可以确保Block不持有`BlockTable`的强引用,从而避免循环引用。 代码如下所示: ```objc @implementation BlockTable -(void)setAddCell:(AddCellBlock)addCell{ __weak AddCellBlock addCellWeak=addCell; _addCell=addCellWeak; } // ... @end ``` 这种方法的关键在于,Block通过`addCellWeak`这个弱引用传递,不直接持有`BlockTable`的强引用。这样,即使Block内部调用了`self.addCell`,也不会导致循环引用,对象在不再被引用时可以正常释放。 需要注意的是,虽然这种方法在某些场景下有效,但并不是所有情况都适用。如果Block需要长期持有并多次执行,或者在Block执行后需要释放`BlockTable`,那么仍然需要使用`weakSelf`来防止循环引用。此外,第三方库和框架可能会在Block执行后不立即释放Block,此时不使用`weakSelf`可能会导致内存泄漏。 理解Block的内存管理和循环引用是iOS开发中的重要技能。虽然在某些特定情况下,可以通过巧妙地使用弱引用来避免`weakSelf`,但在大多数情况下,遵循标准的最佳实践(如使用`weakSelf`)仍然是更安全、更可靠的选择。开发者应根据项目具体需求和内存管理规则灵活运用。
剩余7页未读,继续阅读
- 粉丝: 2
- 资源: 872
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助