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] 10
test2[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] demo
test2[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;
复制代码
评论