欢迎来到天天文库
浏览记录
ID:49614982
大小:34.22 KB
页数:13页
时间:2020-03-02
《block使用小结、在arc中使用block、如何防止循环引用.doc》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、引言使用block已经有一段时间了,感觉自己了解的还行,但是几天前看到CocoaChina上一个关于block的小测试主题: 【小测试】你真的知道blocks在Objective-C中是怎么工作的吗?,发现竟然做错了几道, 才知道自己想当然的理解是错误的,所以抽时间学习了下,并且通过一些测试代码进行测试,产生这篇博客。Block简介(copy一段)Block作为C语言的扩展,并不是高新技术,和其他语言的闭包或lambda表达式是一回事。需要注意的是由于Objective-C在iOS中不支持GC机制,使用Block必须自己
2、管理内存,而内存管理正是使用Block坑最多的地方,错误的内存管理 要么导致returncycle内存泄漏要么内存被提前释放导致crash。 Block的使用很像函数指针,不过与函数最大的不同是:Block可以访问函数以外、词法作用域以内的外部变量的值。换句话说,Block不仅实现函数的功能,还能携带函数的执行环境。可以这样理解,Block其实包含两个部分内容1.Block执行的代码,这是在编译的时候已经生成好的;2.一个包含Block执行时需要的所有外部变量值的数据结构。 Block将使用到的、作用域附近到的变量的值建
3、立一份快照拷贝到栈上。Block与函数另一个不同是,Block类似ObjC的对象,可以使用自动释放池管理内存(但Block并不完全等同于ObjC对象,后面将详细说明)。Block基本语法基本语法在本文就不赘述了,同学们自学。Block的类型与内存管理根据Block在内存中的位置分为三种类型NSGlobalBlock,NSStackBlock,NSMallocBlock。·NSGlobalBlock:类似函数,位于text段;·NSStackBlock:位于栈内存,函数返回后Block将无效;·NSMallocBlock:
4、位于堆内存。1、NSGlobalBlock如下,我们可以通过是否引用外部变量识别,未引用外部变量即为NSGlobalBlock,可以当做函数使用。1234{ //createaNSGlobalBlock float (^sum)(float, float)=^(float a, float b){ 56789 return a+b; }; NSLog(@"blockis%@",sum); //blockis<__NSGlobalBlock__:0x47d0>}2、NSStackBl
5、ock如下:12345678910111213141516171819{ NSArray *testArr=@[@"1", @"2"]; void (^TestBlock)(void)=^{ NSLog(@"testArr:%@",testArr); }; NSLog(@"blockis%@",^{ NSLog(@"testArr:%@",testArr); }); //blockis<__NSStackBlock__:0xbfffdac0>
6、//打印可看出block是一个 NSStackBlock, 即在栈上, 当函数返回时block将无效 NSLog(@"blockis%@",TestBlock); //blockis<__NSMallocBlock__:0x75425a0> //上面这句在非arc中打印是 NSStackBlock, 但是在arc中就是NSMallocBlock //即在arc中默认会将block从栈复制到堆上,而在非arc中,则需要手动copy.}203、NSMallocBlock只需要对NSStackBloc
7、k进行copy操作就可以获取,但是retain操作就不行,会在下面说明Block的copy、retain、release操作 (还是copy一段)不同于NSObjec的copy、retain、release操作:·Block_copy与copy等效,Block_release与release等效;·对Block不管是retain、copy、release都不会改变引用计数retainCount,retainCount始终是1;·NSGlobalBlock:retain、copy、release操作都无效;·NSStack
8、Block:retain、release操作无效,必须注意的是,NSStackBlock在函数返回后,Block内存将被回收。即使retain也没用。容易犯的错误是[[mutableAarryaddObject:stackBlock],(补:在arc中不用担心此问题,因为arc中会默认将实例化的block拷贝到堆上)
此文档下载收益归作者所有