block 实质值是一个结构体的指针
当我们在block内部调用一个局部变量 当改变这个局部变量的值是没有办法影响到 block内部的值的 因为block的底层实现是传入block的一个常量值.
static __block 修饰的 当我们调用一一个静态变量 全局变量 我们在block 调用之前修改的之变量的值 会影响到block 中的这些常量的值 因为 block 的底层是传入了这个值 的 指针地址
block 的 储存位置
__NSGlobalBlock__
当我们什么都不做的时候 还是引入的是静态变量 或者 全局变量 这个时候 我们的block是在全局静态区的 也就算常量区 (这个时候内存是系统自己管理的 当程序结束的时候就会释放掉 回收资源)
__NSStackBlock__ 栈区
当我们在block中引入局部变量(基础类型 对象类型)那么此时我们的Block 在栈区 不用我们管理 出了这个函数大括号就释放掉了
__NSMallocBlock__ 堆区
当前栈区的block 经过copy 后 block就会存储在堆区 这个copy :作用的 将栈区的block 拷贝到堆区 (开发人员管理 内存)
block 的循环引用
当我们把block拷贝到堆区的时候 block 会对内部 调用的对象 引用计数加1 因此会引发内存问题
解决方法 第一种方法 Block_release() 发放对该block 进行释放 在block释放的时候里面调用的对象的引用计数就会减一
第二种方法 __block修饰该对象 这个对象的引用计数就不会加一了
我们的block 中调用self.age 此时 我们的block在栈区
当我们的block 调用属性copy block 在堆区
我们在mian.m person 的引用计数为2 release 后 引用计数变为 1 此时 person 不会被销毁
为于堆区的block 也没有办法 调用到person.m 中的dealloc 方法 因此引用计数也为1
解决办法
__block 在MRC下对对象self修饰 __weak 在ARC下对对象self修饰 此时对象的引用计数就不会再加一了
网友评论