【作者前言】:13年入圈,分享些本人工作中遇到的点点滴滴那些事儿,17年刚开始写博客,高手勿喷!以分享交流为主,欢迎各路豪杰点评改进!
1.应用场景:
Block经常被应用于设计模式,界面传值,代码块绑定,增强项目灵活性,提升代码B格等
2.实现目标:
理解Block的循环引用???---面试必备技能
3.代码说明:
1)为何会有循环引用?
正常情况举例
:A --->持有B时 --->会是B的retainCount +1...
在A不持有B时--即Adealloc后给B释放信号--->B接到release信号,retainCount - 1 ---> 当B的retainCount为0时,B的dealloc被调用--->进入自动释放池,释放B中所有的对象--->A就会进入休眠区域,等待外界的界面响应
有正常自然就有不正常的情况~~~
不正常情况
:
A ---->B
B ---->A
互相持有,互相引用,你中由我,我中有你,无法执行析构函数(dealloc),无法释放
2)循环引用的代码
image.png image.png3)循环引用-通常处理方式
①_ _weak 处理
分析 : weak修饰的属性会在出了作用域之后立即释放
self.testStr = @"测试";
//循环引用产生原因: self--->持有属性 block --->block代码块中又持有了self
//解决途径,打破循环引用:self ---> block /weak/--->self
__weak typeof(self)weakSelf = self;
self.block = ^{
//出了代码块作用域, weak---释放
NSLog(@"%@",weakSelf.testStr);
};
②_ _block 处理
分析:_ _block修饰的属性 会在另外开辟新的内存区域,生成新的空间变量
//_ _block :变量捕捉拷贝
//self ---> block --->blockSelf(在另一个内存区域,生成新的空间变量)
//blockSelf = nil; 是为了置为野指针,释放空间
__block ViewController *blockSelf = self;
self.block = ^{
NSLog(@"%@",blockSelf.testStr);
blockSelf = nil;
};
③利用形参处理
分析:self--->block--->self 想办法打破其中一个环节,考虑到使用临时的形参,将block代码块内的self变成一个形参,解决循环引用
self.block = ^(ViewController *vc) {
NSLog(@"%@",vc.testStr);
};
self.block(self);
网友评论