推荐文章
深入研究Block捕获外部变量和__block实现原理
Automatic Reference Counting
研究工具:clang
clang -rewrite-objc main.m
1、被捕获的局部变量在Block中不能被改变
⚠️ 全局变量和静态变量是可以被改变的,因为作用域更广。

2019-01-22 16:15:41.489808+0800 OCDemo[23367:2877052] Block外 global_i = 2,static_global_j = 2,static_k = 2,val = 2
2019-01-22 16:15:41.490085+0800 OCDemo[23367:2877052] Block中 global_i = 3,static_global_j = 3,static_k = 3,val = 1
Program ended with exit code: 0
原因是:作为非对象的局部变量被捕获的是一份copy值,而不是reference地址,不能改变其值。
⚠️ NSMutableArray、NSMutableString等是可以被改变的。
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
NSMutableArray *ayy = [[NSMutableArray alloc] initWithCapacity:10];
int val = 1;
void (^myBlock)(void) = ^{
[ayy addObject: [NSNumber numberWithInteger:1]];
NSLog(@"ayy BLock中 = %@",ayy);
NSLog(@"val BLock中 = %d",val);
};
[ayy addObject: [NSNumber numberWithInteger:2]];
[ayy addObject: [NSNumber numberWithInteger:3]];
NSLog(@"ayy %@", ayy);
myBlock();
}
对于对象变量来说
对于声明为__block的外部对象,在block内部会进行retain,以至于在block环境内能安全的引用外部对象。
对于非对象变量来说

2、Block分类
自己的理解:初始化的时候isa都是_NSConcreteStackBlock,具体运行时根据不通情况变成_NSConcreteGlobalBlock或者_NSConcreteMallocBlock。



3、Block 的循环引用

Resolving Strong Reference Cycles for Closures
Swift版:[Defining a Capture List]
[unowned self, weak delegate = self.delegate!]
weak
:对应生命周期更短的
unowned
: 对应生命周期更长的、非nil
- an unowned reference is used when the other instance has the same lifetime or a longer lifetime.
- An unowned reference is expected to always have a value. never nil
lazy var someClosure: (Int, String) -> String = {
[unowned self, weak delegate = self.delegate!] (index: Int, stringToProcess: String) -> String in
// closure body goes here
}

Objective-C版
__weak __typeof(self) weakSelf = self
4、Block 和 函数指针 的理解
- 函数指针是对一个函数地址的引用,这个函数在编译的时候就已经确定了。
-
Block是一个对象,包含属性和方法(函数指针)。
image.png

网友评论