您的位置:首页 > 移动开发 > Objective-C

Objective-C Blocks 小测验

2016-04-25 11:10 344 查看
http://ios.jobbole.com/84621/

今天看到一个有意思的 block 测试网站,记录一下。

你可以在这里来先测试一下:

Objective-C Blocks Quiz


Example A

Objective-C

123456void exampleA() { char a = 'A'; ^{ printf("%cn", a); }();}
解释:
这段代码在 MRC 和 ARC 的情况下都能正确执行。
因为
exampleA
的函数栈,在 block 执行完之前,并不会 pop,所以,无论函数中的 block 是在 stack 或是 heap 中,都能够被正确执行。

Example B

Objective-C

1

2

3

4

5

6

7

8

9

10

11

12

13

voidexampleB_addBlockToArray(NSMutableArray*array){

charb='B';

[array
addObject:^{

printf("%cn",b);

}];

}

voidexampleB(){

NSMutableArray*array=[NSMutableArrayarray];

exampleB_addBlockToArray(array);

void(^block)()=[array
objectAtIndex:0];

block();

}

解释:

这段代码只有在 ARC 的情况下才能正确执行。

在 MRC 的情况下,block 分配在栈上,在
exampleB_addBlockToArray
返回之后,函数栈被弹出,这个 block 的地址就不再合法了。

在 ARC 的情况下,block 将会被拷贝到堆中,可以合法使用。


Example C

Objective-C

123456789101112void exampleC_addBlockToArray(NSMutableArray *array) { [array addObject:^{ printf("Cn"); }];} void exampleC() { NSMutableArray *array = [NSMutableArray array]; exampleC_addBlockToArray(array); void (^block)() = [array objectAtIndex:0]; block();}
解释:
这段代码在 MRC 和 ARC 的情况下都能正确执行。
因为
exampleC_addBlockToArray
中的 block 并没有捕获任何变量,是一个
NSGlobalBlock
,既不在堆中,也不在栈上,所以可以像普通的 C 函数一样访问,不会存在任何问题。

Exapmle D

Objective-C

1

2

3

4

5

6

7

8

9

10

11

12

typedefvoid(^dBlock)();

dBlockexampleD_getBlock(){

chard='D';

return^{

printf("%cn",d);

};

}

voidexampleD(){

exampleD_getBlock()();

}

解释:

这段代码只有在 ARC 的情况下才能正确执行。

block 分配在栈上,如果是 ARC,将会被拷贝到堆上。而 MRC 的情况下,函数执行结束,这个地址就不存在了,而且编译器会报错:
error: returning block that lives on the local stack


Example E




typedef void (^eBlock)();

eBlock exampleE_getBlock() {
char e =
'E';
void (^block)() = ^{
printf("%cn", e);
};
return block;
}

void exampleE() {
eBlock block =
exampleE_getBlock();
block();
}


解释:

这段代码只有在 ARC 的情况下才能正确执行。

Exapmle D
的情况很类似,只不过这儿编译器在 MRC 情况下不会报错。


结论

ARC
大法好!

如果不使用 ARC(我觉得现在应该没有不用 ARC 的吧…)需要在传递 block 的时候,使用
block = [[block copy] autorelease]
,这样可以让 block 拷贝到堆中。

声明:本文内容并非原创,而是大部分引用自上面所说的网站
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: