【小测试】你真的知道blocks在Objective-C中是怎么工作的吗?

转载 2015年07月08日 09:38:11

你真的知道blocks在Objective-C中是怎么工作的吗?


来做个小测试看看吧。


所有的例子都以下版本上测试过。


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


例子1

?

1

2

3

4

5

6

void exampleA() {

  char a = 'A';

  ^{

    printf("%c\n", a);

  }();

}



这个例子:


A.始终能够正常运行                B.只有在使用ARC的情况下才能正常运行

C.不使用ARC才能正常运行   D.永远无法正常运行



例子2:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

void exampleB_addBlockToArray(NSMutableArray *array) {

  char b = 'B';

  [array addObject:^{

    printf("%c\n", b);

  }];

}

  

void exampleB() {

  NSMutableArray *array = [NSMutableArray array];

  exampleB_addBlockToArray(array);

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

  block();

}



A.始终能够正常运行                B.只有在使用ARC的情况下才能正常运行

C.不使用ARC才能正常运行   D.永远无法正常运行




例子3

?

1

2

3

4

5

6

7

8

9

10

11

12

void exampleC_addBlockToArray(NSMutableArray *array) {

  [array addObject:^{

    printf("C\n");

  }];

}

  

void exampleC() {

  NSMutableArray *array = [NSMutableArray array];

  exampleC_addBlockToArray(array);

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

  block();

}



A.始终能够正常运行                B.只有在使用ARC的情况下才能正常运行

C.不使用ARC才能正常运行   D.永远无法正常运行



例子4

?

1

2

3

4

5

6

7

8

9

10

11

12

typedef void (^dBlock)();

  

dBlock exampleD_getBlock() {

  char d = 'D';

  return ^{

    printf("%c\n", d);

  };

}

  

void exampleD() {

  exampleD_getBlock()();

}



A.始终能够正常运行                B.只有在使用ARC的情况下才能正常运行

C.不使用ARC才能正常运行   D.永远无法正常运行




例子5

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

typedef void (^eBlock)();

  

eBlock exampleE_getBlock() {

  char e = 'E';

  void (^block)() = ^{

    printf("%c\n", e);

  };

  return block;

}

  

void exampleE() {

  eBlock block = exampleE_getBlock();

  block();

}




A.始终能够正常运行                B.只有在使用ARC的情况下才能正常运行

C.不使用ARC才能正常运行   D.永远无法正常运行



答案

例子1


A正确。这个例子可以正常运行。储存exampleA的栈只有在block停止执行之后才会释放,因此,无论此Block由系统分配到栈中还是我们自己手动分配到堆中,它都可以正常执行。



例子2


B正确。如果不使用ARC,这个block是一个NSStackBlock,分配给exampleB_addBlockToArray的栈上。而当它在exampleB中执行的时候,由于栈被清空,block不再有效。


而使用ARC的话,block会分配到堆中,作为一个自动释放的NSMallocBlock



例子3


A正确


由于block在自己的环路中不会抓取任何变量,它不需要在在运行的时候设置state,它会作为一个NSGlobalBlock编译。它既不是栈也不是堆,而是代码片段的一部分。所以它始终都能正常运行。



例子4


B正确。这个例子和例子2类似。如果不使用ARC,block会在exampleD_getBlock的栈上创建起来。然后当功能返回的时候会立即失效。


然而,以这个例子来说,这个错误非常明显,所以编译器进行编译会失败,错误提示是:error: returning block that lives on the local stack(错误,返回的block位于本地的栈)。



例子5


B正确。这个例子和例子4类似,除了编译器没有认出有错误,所以代码会进行编译然后崩溃。更糟糕的是,这个例子比较特别,如果你关闭了优化,则可以正常运行。所以在测试的时候需要注意。


而如果使用ARC的话,block则会正确的位于堆上,作为一个自动释放的NSMAllocBlock。



结论

这套小测试有什么意义呢?意义就是要一直使用ARC。使用ARC,block大部分情况下都可以正常运行。


如果不使用ARC,谨慎起见,可以block = [[block copy] autorelease],这样block会比申明它的栈flame的有效期长。这样block会被作为一个NSMAllocBlock强制复制到堆上。


但是,当然不会这么简单,根据苹果的文档,


Block只有当你在ARC模式下传递block到栈上才会工作,比如说返回的时候。你不需要再次调用Block Copy了。但是当block从栈上传递到 arrayWithObjects: 和其他做了一个retain的方法是时,仍然需要使用[^{} copy]。



但是有一个LLVM的维护者之后也说过:


我们认为这是编译器的bug,它现在已经修复了。但是Xcode以后是否会在以后发布的新版本中解决这个问题,我也不知道。



所以,希望,苹果也把它认为是一个bug,在以后的新版本中会解决这个问题。让我们看看会怎么样吧。




原文:http://blog.parse.com/2013/02/05/objective-c-blocks-quiz/      


相关文章推荐

你真的知道blocks在Objective-C中是怎么工作的吗?

关键提示:你首先需要搞清楚这个block是分配在哪里的内存,NSMallocBlock,NSStackBlock,NSGlobalBlock,然后再判断arc和非arc状态下的区别,祝你好运哦,亲。-...

Objective-C的blocks语法

OC中的blocks和C++中的函数指针类似,从外观和使用上可以看出 Int(*CFunc)(int a);   //C语言的函数指针。 调用   Intret=(CFunc)(10); In...

Effective Objective-C 2.0: Item 37: Understand Blocks

Effective Objective-C 2.0 介绍Blocks的文章,有些论点比较新颖,觉得不错,值得一看

Objective-C Blocks 小测验

http://ios.jobbole.com/84621/ 今天看到一个有意思的 block 测试网站,记录一下。 你可以在这里来先测试一下: Objective-C Blocks Quiz...

Effective Objective-C 2.0: Item 39: Use Handler Blocks to Reduce Code Separation

Item 39: Use Handler Blocks to Reduce Code Separation A common paradigm in programming a user int...

【Effective Objective-C 2.0读书笔记】第六章:块(Blocks)和大中枢派发(GCD)

继续这本书的读书笔记,希望在其中也加入自己的一些总结,以加深理解。之前这一章写了很多了,保存到草稿箱中,不知道为何丢失了,真是可惜,看来CSDN的MarkDown编辑器还存在一些bugs,在它打上补丁...

Objective-C中Blocks块的介绍

*注:解释内容主要参考《Objective-C 高级编程》 1.介绍:   Blocks是C语言的扩充功能:带有自动变量(局部变量)的匿名函数。   Blocks的语法:^  返回值类型  参数列表 ...

使用code::blocks搭建objective-c的IDE开发环境,支持外部引用.h和.m文件

1. 安装和下载code::blocks http://www.codeblocks.org/ 2. 配置code::blocks环境 打开code::blocks → 菜单...
  • sonikk
  • sonikk
  • 2013-04-03 16:40
  • 1807

《Objective-C 高级编程》干货三部曲(二):Blocks篇

这一章讲解了Block相关的知识。因为作者将Objective-C的代码转成了C++的代码,所以第一次看的时候非常吃力,我自己也不记得看了多少遍了。这篇总结不仅仅只有这本书中的内容,还有一点在其他博客...

初探Objective-c 4:OC中的Blocks

Blocks 是什么?如果把OC看作C语言的超集,那么Blocks就是C语言的扩充功能。用一句话来概括Blocks:带有自动变量(局部变量)的匿名函数。匿名函数,就是不带有名称的函数。Blocks的基...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)