Block中weak/strong self用法
// 写法
__weak __typeof(self)weakSelf = self;
block blk = ^() {
__strong __typeof(weakSelf)strongSelf = weakSelf;
}
_ typeof _() __typeof() 是对c语言的编译扩展,标准C要求会对带有双下划线方法或变量进行编译器预处理
1.typeof()其实和上面两者相同,typeof()本质上是对C的扩展,这个语法来自于C语言
weak strong 所起的作用
通常这种用法是成对出现的__ weak __ strong
__weak 是将变量变成弱引用,确保不会产生循环引用的问题。
__strong 强引用,则是在block整个运行周期内防止由于挂载对象的释放导致weakSelf被释放,导致的Crash。
Block详解
Block本质是一个函数指针,指向我们要使用的函数,他可以放在栈区, 堆区, 静态区,都是可以被调用的。
Block有三种类型
1._NSConcreteGlobalBlock 全局静态Block,不会访问外部的变量,也就是说这个Block没有对外部变量的任何引用,基本上就是打印逻辑之类或就是内部逻辑。
2._NSConcreteStackBlock 保存在栈中的Block,当函数返回时被销毁,不使用copy修饰就相当于保存在栈中的Block
3._NSConcreteMallocBlock 保存在堆中的Block,当引用计数为0时被销毁,使用copy修饰就会保存在堆中
全局静态block只有在应用被结束时才会被释放,保存在栈中的Block他会随着函数调用结束被销毁,再次调用就会产生空指针异常。
保存在堆中的Block会随着对象的销毁而结束,只要对象不销毁,我们就可以调用到在堆中的Block,它会随着对象的销毁而结束。
Block存储区域问题
Block有三种存储方式: 栈、全局、堆。Block对象中包含一个ISA属性,可以根据该属性哦按你算存储位置。
注意:在ARC情况下没有存在栈上这种情况,只有存在Global以及Malloc这两种情况,而如果是MRC则确实存在栈、全局、堆这三种情况。
有一种比较特殊的存在栈中的Block的情况,就是仅仅只是定义了Block但是并未将其赋值给某一个变量,此时它存放在栈内存区域,例如将定义好的的Block存放在数组中的这种情况。
全局Block
1.定义在函数外部的的Block是Global类型。
2.定义在函数内部且没有捕获任何变量,那么它也是全局的。
3.有操作变量的这种Block则会存放到堆中,这个存放过程是ARC自动控制的过程。
Block的copy操作
1.栈上调用copy会复制到堆上
2.全局block调用copy什么也不做
3.堆上调用block引用计数增加 // 内存释放和应用计数强相关