Block 中访问局部变量
int main(int argc, const char * argv[]) { int testNum = 10; void(^testNumBlock)() = ^{ NSLog(@"%d",testNum); }; testNumBlock(); return 0; } 打印结果:10
复制代码
int main(int argc, const char * argv[]) { int testNum = 10; void(^testNumBlock)() = ^{ NSLog(@"%d",testNum); }; testNum = 20; testNumBlock(); return 0; } 打印结果:10
复制代码
int main(int argc, const char * argv[]) { int testNum = 10; void(^testNumBlock)() = ^{ testNum = 20; //报错 NSLog(@"%d",testNum); }; testNumBlock(); return 0; }
复制代码
Block 内访问__block 修饰的局部变量
__block int testNum = 10; void(^testNumBlock)() = ^{ NSLog(@"%d",testNum); }; testNum = 20; testNumBlock(); 打印结果:20
复制代码
int main(int argc, const char * argv[]) { __block int testNum = 10; void(^testNumBlock)() = ^{ testNum = 20; NSLog(@"%d",testNum); }; testNumBlock(); return 0; } 打印结果:20
复制代码
Block 内访问全局变量
int testNum = 10; int main(int argc, const char * argv[]) { void(^testNumBlock)() = ^{ NSLog(@"%d",testNum); }; testNumBlock(); return 0; } 打印结果:10
复制代码
int testNum = 10; int main(int argc, const char * argv[]) { void(^testNumBlock)() = ^{ NSLog(@"%d",testNum); }; testNum = 20; testNumBlock(); return 0; } 打印结果:20
复制代码
int testNum = 10; int main(int argc, const char * argv[]) { void(^testNumBlock)() = ^{ testNum = 20; NSLog(@"%d",testNum); }; testNumBlock(); return 0; } 打印结果:20
复制代码
Block 内访问静态变量
int main(int argc, const char * argv[]) { static int testNum = 10; void(^testNumBlock)() = ^{ NSLog(@"%d",testNum); }; testNumBlock(); return 0; } 打印结果:10
复制代码
int main(int argc, const char * argv[]) { static int testNum = 10; void(^testNumBlock)() = ^{ NSLog(@"%d",testNum); }; testNum = 20; testNumBlock(); return 0; } 打印结果:20
复制代码
int main(int argc, const char * argv[]) { static int testNum = 10; void(^testNumBlock)() = ^{ testNum = 20; NSLog(@"%d",testNum); }; testNumBlock(); return 0; } 打印结果:20
复制代码
Block 作为参数传递
typedef void(^TestBlock)();NSMutableArray *array;void test(){ int a = 10; TestBlock blcok = ^{ NSLog(@"%d",a); }; [array addObject:blcok]; NSLog(@"%@",blcok);}
int main(int argc, const char * argv[]) {
array = [[NSMutableArray alloc]init]; test(); TestBlock blockk = [array lastObject]; blockk(); NSLog(@"%@",blockk); return 0;} 结果:在ARC下:test2[2423:124143] <__NSMallocBlock__: 0x1004037f0>test2[2423:124143] 10test2[2423:124143] <__NSMallocBlock__: 0x1004037f0>在非ARC下:程序崩溃 test2[2449:125851] <__NSStackBlock__: 0x7fff5fbff6f8>
复制代码
1、在非 ARC 下,TestBlock 的isa指向__NSStackBlock__,当函数退出后,相应的堆被销毁,block也就不存在了,在经过copy或retain之后,对象的类型从__NSStackBlock__变为了__NSMallocBlock__,在函数结束后依然可以访问,在非 ARC 环境下,copy或retain了block后一定要在使用后release,不然会有内存泄露,而且泄露点是在系统级,在 Instruments 里跟不到问题触发点,比较上火。
2、ARC 情况下,系统会将捕获了外部变量的block进行了copy。所以返回类型为__NSMallocBlock__,在函数结束后依然可以访问
如果把blcok中的代码不再访问变量:
TestBlock blcok = ^{ NSLog(@"demo"); };结果:ARC和非ARC得结果一致test2[2484:128052] <__NSGlobalBlock__: 0x100005290>test2[2484:128052] demotest2[2484:128052] <__NSGlobalBlock__: 0x100005290>
复制代码
Block 作为返回值
- (testBlcok) myTestBlock { __block int val = 10; return ^{ NSLog(@"val = %d", val); };}结果:Xcode就会提示报错Returning block that lives on the local stack
复制代码
在向外传递block的时候一定也要做到,传给外面一个在堆上的,autorelease的对象。
- (testBlcok) myTestBlock { __block int val = 10; return [[^{ NSLog(@"val = %d", val); } copy] autorelease];}
复制代码
- (testBlcok) myTestBlock { __block int val = 10; return ^{ NSLog(@"val = %d", val); };}结果:正常
复制代码
在 ARC 环境下,当block作为参数返回的时候,block也会自动被移到堆上。
Block 作为属性
ARC 和非 ARC 得声明一样
@property (strong, nonatomic) TestBlock *strongBlock;@property (copy, nonatomic) TestBlock *copyBlock;
复制代码
评论