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

Objective-C Blocks Quiz

2015-11-04 11:07 591 查看
http://blog.parse.com/learn/engineering/objective-c-blocks-quiz/

Do you really know how blocks work in Objective-C? Take this quiz to find out.

All of these examples have been verified with this version of LLVM:

Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin11.4.2
Thread model: posix

Example A

void exampleA() {
char a = 'A';
^{
printf("%cn", a);
}();
}

This example

always works.only works with ARC.
only works without ARC.never works.

Example B

void exampleB_addBlockToArray(NSMutableArray *array) {
char b = 'B';
[array addObject:^{
printf("%cn", b);
}];
}

void exampleB() {
NSMutableArray *array = [NSMutableArray array];
exampleB_addBlockToArray(array);
void (^block)() = [array objectAtIndex:0];
block();
}

This example

always works.only works with ARC.
only works without ARC.never works.

Example C

void exampleC_addBlockToArray(NSMutableArray *array) {
[array addObject:^{
printf("Cn");
}];
}

void exampleC() {
NSMutableArray *array = [NSMutableArray array];
exampleC_addBlockToArray(array);
void (^block)() = [array objectAtIndex:0];
block();
}

This example

always works.only works with ARC.
only works without ARC.never works.

Example D

typedef void (^dBlock)();

dBlock exampleD_getBlock() {
char d = 'D';
return ^{
printf("%cn", d);
};
}

void exampleD() {
exampleD_getBlock()();
}

This example

always works.only works with ARC.
only works without ARC.never works.

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();
}

This example

always works.only works with ARC.
only works without ARC.never works.

Conclusions

So, what’s the point of all this? The point is always use ARC. With ARC, blocks pretty much always work correctly. If you’re not using ARC, you better defensively 
block = [[block copy] autorelease]
 any
time a block outlives the stack frame where it is declared. That will force it to be copied to the heap as an 
NSMallocBlock
.

Haha! No, of course it’s not that simple. According to Apple:

Blocks “just work” when you pass blocks up the stack in ARC mode, such as in a return. You don’t have to call Block Copy any more. You still need to use 
[^{} copy]
 when passing “down” the stack into 
arrayWithObjects:
 and
other methods that do a retain.

But one of the LLVM maintainers later said:

We consider this to be a compiler bug, and it has been fixed for months in the open-source clang repository. What that means for any hypothetical future Xcode release, I cannot say. 


So, hopefully Apple was describing a workaround for bugs that existed at the time their guide was written, and everything should work smoothly with ARC and LLVM in the future. But watch out. 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: