小编给大家分享一下block循环引用问题的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
从iOS4.0开始,objective C中引入了block技术。block跟标准c的函数类似,block的引入使得代码回调更加方便。
优点:
(1)、回调直接写在需要触发的地方,使代码更具有连续性。
(2)、在代码块内部可以访问局部变量
但是,如果block使用不慎,将引起内存泄露。
1、为啥会引起内存泄露?
在block代码块里,如果传入了代码块外部的对象,block会对该对象进行retain,持有该对象,造成循环引用。
eg:
@interface TestBlockObject : NSObject
- (void)invokeBlock:(void (^)(void))testBlock;
@end
@implementation TestBlockObject
- (void)invokeBlock:(void (^)(void))testBlock{
NSLog(@"TestBlockObject");
}
@end
//调用
@interface ViewController ()
{
TestBlockObject *ob;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
ob = [TestBlockObject new];
[ob invokeBlock:^{
//引起循环引用
[self testPrint];
}];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)testPrint{
NSLog(@"哈哈");
}
@end
引起循环引用的地方
[ob invokeBlock:^{
//引起循环引用
[self testPrint];
}];
ViewController(self)持有ob,ob的block中持有self,导致了循环引用。self对象将不会被销毁,从而ob也不会被销毁,引起内存泄露。
2、解决循环引用方法
使用以下的代码替换红色代码
__weak typeof(self) weakSelf = self;
[ob invokeBlock:^{
if (weakSelf) {
[weakSelf testPrint];
}
}];
通过将self转换成weak对象,然后再block中使用,破坏循环引用。
3、特殊的地方
若在ViewController的viewDidLoad加入下方的代码,是不会导致循环引用的。因为代码块是类方法,ViewController没有持有该部分内存。当block执行结束后,block就会被释放掉,因而self就不会被持有。
[UIView animateWithDuration:0.5 animations:^{
[self testPrint];
}];
以上是“block循环引用问题的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。