ios block常见的错误(二)——循环引用
这篇博文继续block的常见错误——循环引用。
循环引用是很多初学者不能察觉的,其产生的原因,是block中的代码会对对象进行强引用。
读者请阅读示例代码1,并思考示例代码1所创建的对象能否被正常销毁?
示例代码1:
//DemoObj.m @interface DemoObj ()
@property (nonatomic, strong) NSMutableArray *myBlocks;
@end #pragma mark 将代码改为调用self的方法 -(NSMutableArray *)myBlocks
{
if (_myBlocks == nil) {
_myBlocks = [NSMutableArray array];
} return _myBlocks;
} - (instancetype)init
{
self = [super init];
if (self) {
int(^sum)(int, int) = ^(int x, int y) {
return [self sum:x y:y];
};
[self.myBlocks addObject:sum];
} return self;
} -(int)sum:(int) x y:(int)y
{
return x + y;
} #pragma mark 对象被释放时自动调用
- (void)dealloc
{
NSLog(@"DemoObj被释放");
}
答案是不能正常释放的。读者不妨在xcode中试试。
产生原因在block代码中出现了self:
int(^sum)(int, int) = ^(int x, int y) {
return [self sum:x y:y];
};
此时sum的block对self强引用,在加上self对myBlocks强引用:
@property (nonatomic, strong) NSMutableArray *myBlocks;
以及sum block被添加到数组时,会被数组强引用:
[self.myBlocks addObject:sum];
这三个引用之间形成了循环引用,如下图:
循环引用的结果就是对象无法被释放!
碰到这类问题,程序员如何解除循环引用呢?
有以下几种解决方案:
1.在block代码中不要引用self以及其他局部变量;如
int(^sum)(int, int) = ^(int x, int y) {
return [self sum:x y:y];
};
修改成
int(^sum)(int, int) = ^(int x, int y) {
return x + y;
};
2.使用__weak关键字,可以将局部变量声明为弱引用
如:
- (instancetype)init
{
self = [super init];
if (self) {
int(^sum)(int, int) = ^(int x, int y) {
return [self sum:x y:y];
};
[self.myBlocks addObject:sum];
} return self;
}
修改为:
- (instancetype)init
{
self = [super init];
if (self) {
__weak DemoObj *weakSelf = self;
int(^sum)(int, int) = ^(int x, int y) {
return [weakSelf sum:x y:y];
};
[self.myBlocks addObject:sum];
} return self;
}
block的循环引用就说到这,下一篇继续来讲解block的常见错误
ios block常见的错误(二)——循环引用的更多相关文章
- ios block常见的错误(三)——并发编程的block引用
在一些技术型的企业里面,有关block面试笔试题,将会问得很深,如下例子: 请问DemoObj的对象能否正确释放,为什么? //DemoObj.m @interface DemoObj() @prop ...
- ios block常见的错误(一)
Block是OC中的一种数据类型,在iOS开发中被广泛使用. 在实际的使用和面试过程中,经常发现同事或面试者对block了解得不够透彻,本博文将列举常见block错误来对其加深理解. 示例代码1: ; ...
- iOS 面试题(四):block 什么时候需要构造循环引用 --转自唐巧
问题 有没有这样一个需求场景,block 会产生循环引用,但是业务又需要你不能使用 weak self? 如果有,请举一个例子并且解释这种情况下如何解决循环引用问题. 答案 需要不使用 weak se ...
- block本质探寻八之循环引用
说明:阅读本文,请参照之前的block文章加以理解: 一.循环引用的本质 //代码——ARC环境 void test1() { Person *per = [[Person alloc] init]; ...
- oracle数据库管理系统常见的错误(二)
oracle数据库,对于新手来说总会遇到这样的问题: 相信大家都遇到了这样的问题,说实话,我曾经就遇到过这样的问题,但是不好意思问旁边的技术大咖,都有点怀疑人生了,然后自己在网上去查找原因,结果发现, ...
- block中self会造成循环引用问题
将代码块中的 self换成unsafeSelf __unsafe_unretained 与 __weak 99%相同 __weak 当对象释放之后 会自动设置为nil 而__unsafe_unreta ...
- iOS Block循环引用
在介绍block循环引用前我们先了解一下typeof. typeof是什么??? typeof 是一个一元运算,放在一个运算数之前,运算数可以是任意类型. 它返回值是一个字符串,该字符串说明运算数的类 ...
- IOS block 循环引用的解决
在介绍block循环引用前我们先了解一下typeof. typeof是什么??? typeof 是一个一元运算,放在一个运算数之前,运算数可以是任意类型. 它返回值是一个字符串,该字符串说明运算数的类 ...
- Block 循环引用(上)
iOS的内存管理机制 Objective-C在iOS中不支持GC(垃圾回收)机制,而是采用的引用计数的方式管理内存. 引用计数:在引用计数中,每一个对象负责维护对象所有引用的计数值.当一个新的引用指向 ...
随机推荐
- 北京市基本医疗保险A类定点医疗机构名单(2010-09-29)
1.中国医学科学院北京协和医院 2.首都医科大学附属北京同仁医院 3.首都医科大学宣武医院 4.首都医科大学附属北京友谊医院 5.北京大学第一医院 6.北京大学人民医院 7.北京大学第三医院 8.北京 ...
- 使用HTML5画柱状图
柱状图在很多应用中都比较常见,例如投票结果的统计分析,企业销售数据的统计分析等等. 需求分析: 一个柱状图一般包含以下几部分: 1.标题 2.横坐标(含标题) 3.竖坐标 (含标题.刻度 ...
- easyui input设置为disabled提交后获取不到属性值
在做网站管理后台的用户修改功能时,由于当前用户修改个人信息时规定用户名不能修改,故使用了input标签的disabled属性,但是在提交数据后却发现用户名显示为空了.后 来一查才知道input设置为d ...
- Protobuf 语法指南
英文: Proto Buffers Language Guide 本指南描述了怎样使用protocol buffer 语法来构造你的protocol buffer数据,包括.proto文件语法以及怎样 ...
- Word 页眉插入自动标题(页眉显示章节标题)
做word文档时有时候需要将章节标题加到页眉中,这里实现自动获取和自动更新页眉里面的标题 1.双击页眉,输入固定文字作为页眉左边的显示,然后敲2下table键,为接下来插入自动标题做好准备,如下图: ...
- 原创D3D几何实例化的DEMO
CUBE的几何实例化DEMO 鼠标右键按下并拖动 旋转视角WSAD 前后左右RF ...
- 变量声明置顶规则、函数声明及函数表达式和函数的arguments属性初始化
一.变量声明和变量赋值: if (!("a" in window)) { ; } alert(a);//a为? 你可能认为alert出来的结果是1,然后实际结果是“undefine ...
- Golang 中使用多维 map
http://tnt.wicast.tk/2015/11/02/golang-multiple-dimension-map/ Golang 的 XML/JSON 解析库乍看使用起来很方便,只要构造一样 ...
- Transform导入数据源TR1008错误
cognos在建设初期开发者们都常常遇到的一个问题,在这里做一下小小的总结. iqd作为Transform的数据源导入数据的时候遭遇TR1008错误 注意: 从报错的内容可以看出transform不能 ...
- [CSS3]Clearfix
<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="index ...