经验之谈—让你看明白block
程序员文章站
2022-07-05 23:35:23
其实我感觉不经常使用block的朋友,对block应该是比较陌生的,那么现在我们来扒开block的真面目,看看block的本质
普通的局部变量,block内部只会引用它初始的值(block定义那一刻...
其实我感觉不经常使用block的朋友,对block应该是比较陌生的,那么现在我们来扒开block的真面目,看看block的本质
普通的局部变量,block内部只会引用它初始的值(block定义那一刻),不能跟踪它的改变
void test() { int age = 10; void (^block)() = ^{ // 普通的局部变量,block内部只会引用它初始的值(block定义那一刻),不能跟踪它的改变 nslog(@"----age=%d", age); }; age = 20; block(); }
这里的结果是10;其实在编译的时候,是相当于这样的:
void test2() { int age = 10; void (^block)() = ^{ // 普通的局部变量,block内部只会引用它初始的值(block定义那一刻),不能跟踪它的改变 nslog(@"----age=%d", 10); }; age = 20; block(); }
这里的这个值 是死的。所以无论你后面把age改成多少,block都不关心。换句话说:这里的age是局部变量,出了大括号就死了,所以直接把这个10拿过来,比较安全
我们看一下,被block引用的变量的情况:
block内部能够一直引用被__block修饰的变量
void test3() { __block int age = 10; void (^block)() = ^{ // block内部能够一直引用被__block修饰的变量 nslog(@"----age=%d", age); }; age = 20; block(); }
这里:block能一直监听着这个age的值的改变(无论是局部变量还是全局变量),所以这里打印出来的是age是20
__block修饰的变量,就能保住这个变量的命
这里我们来看一下,被static修饰的变量,是静态变量,静态是永远在内存中,所以block看到static修饰的这个变量是永远存在内存中的,那么block就能每次都能拿到这个变量,所以你age的值的改变。block都能拿到,所以这是动态访问的,不是把10直接拿过来
void test4() { static int age = 10; void (^block)() = ^{ // block内部能够一直引用被static修饰的变量 nslog(@"----age=%d", age); }; age = 20; block(); }
int num = 10; void test5() { void (^block)() = ^{ // block内部能够一直引用全局变量 nslog(@"----num=%d", num); }; num = 20; block(); }
这里打印出来的num 是20 。为什么呢?
因为这里的num是全局变量,那么既然是全局变量,就一直在内存中,block就能实时跟新这个值的改变。
总结,那么我们现在判断的时候,我们只需要判断这个变量是不是马上就销毁了就行了。但是注意一下__block修饰的变量就行