你真的知道blocks在Objective-C中是怎么工作的吗?
2013-09-05 10:23
357 查看
例子1
?
这个例子:
A.始终能够正常运行 B.只有在使用ARC的情况下才能正常运行
C.不使用ARC才能正常运行 D.永远无法正常运行
例子2:
?
A.始终能够正常运行 B.只有在使用ARC的情况下才能正常运行
C.不使用ARC才能正常运行 D.永远无法正常运行
例子3
?
A.始终能够正常运行 B.只有在使用ARC的情况下才能正常运行
C.不使用ARC才能正常运行 D.永远无法正常运行
例子4
?
A.始终能够正常运行 B.只有在使用ARC的情况下才能正常运行
C.不使用ARC才能正常运行 D.永远无法正常运行
例子5
?
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/
?
A.始终能够正常运行 B.只有在使用ARC的情况下才能正常运行
C.不使用ARC才能正常运行 D.永远无法正常运行
例子2:
?
C.不使用ARC才能正常运行 D.永远无法正常运行
例子3
?
C.不使用ARC才能正常运行 D.永远无法正常运行
例子4
?
C.不使用ARC才能正常运行 D.永远无法正常运行
例子5
?
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中是怎么工作的吗?
- 【小测试】你真的知道blocks在Objective-C中是怎么工作的吗?
- 你真的知道blocks在Objective-C中是怎么工作的吗?
- 你真的知道blocks在Objective-C中是怎么工作的吗?
- blocks在Objective-C中是怎么工作的
- blocks在Objective-C中是怎么工作的?
- 勤奋的人是怎么工作的。。。。。。。。。。看看Orx的作者更新Orx的频率就知道了
- Objective C SEl 和@selector是怎么工作的||How do SEL and @selector work in iphone sdk?
- 谈Objective-C Blocks的实现 (转载)
- 编译器是怎么工作的?使用yacc 和lex 写一个计算器(1)
- 选人控件EntityEditor在非本机下访问时,Check按钮无法工作,怎么解决?
- 【军哥谈CI框架】之入门教程之第二讲:分析CI结构和CI是怎么工作的
- 工作在IT这个行当里你应该知道的10个小秘密 ZT
- 怎么知道索引是否生效
- 让任何杀毒软件都无法安装和运行的病毒,有谁见过并且知道该怎么办吗?
- 我该怎么安排下属的工作-项目经理如何分配任务
- 看我是怎么发外链的,这些都是从长期的工作总得到的经验
- Windows下用Code::Blocks+MingGW进行OpenGL2.0开发(使用GLEW库)的准备工作
- 测试好多都是性能小白,虽学了些性能知识,但在实际工作做开展性能测试,都很茫然,求指导,应该怎么处理?
- 【实验一】计算机是怎么工作的