block

MRC中分为

* NSConcreteGlobalBlock 全局静态block,不会访问任何外部变量

* NSConcreteStackBlock 保存在栈上的block,函数返回时会被销毁,编译器自动管理(栈内存特点),在MRC模式下初始化之后的非全局静态block都是这种类型,所以需要说明的是,MRC模式下,对于block的引用应该用copy,这样该block就会转变成下面这种类型

* NSConcreteMallocBlock 保存在堆上的block,程序管理生命周期,引用计数为0时才会被销毁。MRC下的栈上block被copy时被copy到堆上,变为MallocBlock。

ARC中去掉了NSConcreteStackBlock,默认block即为NSConcreteMallocBlock。可能苹果觉得ARC的内存管理能力足够强大,释放足够及时,堆上内存如果释放及时,还是有很大优势的,毕竟空间和引用管理比较方便

block对外部变量的使用有一个capture机制,其实质是将其copy进相关struct中供block使用的,内部修改不会影响外部。

如果需要影响外部,则变量申明为_block关键字即可,这样内部对该变量的实用变成了指针引用。

以上说明适用于分配在栈上的变量,对于堆上的指针变量天生就能修改原值,但是需要注意:

* 防止循环引用

* 防止野指针

1. 防止循环引用可以用__weak关键字声明指针

2. 防止野指针可以在block内部对其指针引用技术+1,结束之后-1(MRC),或者可以在block内部使用__strong关键字声明指针指向外部用__weak声明的变量

对于第二点可能有同学说,我平时没这么声明也没问题啊,是的,这需要前提,外部函数所属的对象的生命周期比block要长,否则就会因为引用了野指针crash了

火车上不方便补代码,回头补上代码例子

推荐阅读更多精彩内容