Objective-C
Blocks
测试

你真的理解blocks在objective-c中是如何工作的了吗,做个测试检验一下吧。

所有的测试结果已被以下版本的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

一下问题的选项是:都能工作;只在ARC下能工作;只在非ARC下能工作;不能执行

Example A

voidexampleA()
{
  chara
=
'A';
  ^{
    printf("%c\n",
a);
  }();
}

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

选择 always works.
当block结束执行后exampleA的堆也不再继续。因此block被accocated在了
堆上或者栈上,当执行时blocks才有效。

Example B

voidexampleB_addBlockToArray(NSMutableArray*array)
{
  charb
=
'B';
  [array
addObject:^{
    printf("%c\n",
b);
  }];
}
 
voidexampleB()
{
  NSMutableArray*array
= [
NSMutableArrayarray];
  exampleB_addBlockToArray(array);
  void(^block)()
= [array objectAtIndex:0];
  block();
}

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

选择:只在ARC下能正常工作。
不采用ARC的时候,block是一个在exampleB_addBlockToArray的栈上的NSStackBlock 。当exampleB执行的时候,block已经不存在,因为栈已经被释放。

采用ARC机制时,block被实例化到了堆上是一个NSMallocBlock,采用自动释放方法。

Example C

voidexampleC_addBlockToArray(NSMutableArray*array)
{
  [array
addObject:^{
    printf("C\n");
  }];
}
 
voidexampleC()
{
  NSMutableArray*array
= [
NSMutableArrayarray];
  exampleC_addBlockToArray(array);
  void(^block)()
= [array objectAtIndex:0];
  block();
}

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

选择always works.

因为block中没有引用任何变量,他在执行时不需要任何声明,它被编译成了一个NSGlobalBlock。它既不在堆上又不在栈上。有点像c中的函数

在有没有ARC下都可以工作。

Example D

typedefvoid(^dBlock)();
 
dBlock
exampleD_getBlock() {
  chard
=
'D';
  return^{
    printf("%c\n",
d);
  };
}
 
voidexampleD()
{
  exampleD_getBlock()();
}

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

选择 only works with ARC.

它和 example B类似。不采用ARC, block 将会创建在exampleD_getBlock 的栈上当函数返回时就无效了。在这种情况下,编译器会报以下的错误 error:
returning block that lives on the local stack
.

采用ARC block会被编译成一个自动释放的 NSMallocBlock.

Example E

typedefvoid(^eBlock)();
 
eBlock
exampleE_getBlock() {
  chare
=
'E';
  void(^block)()
= ^{
    printf("%c\n",
e);
  };
  returnblock;
}
 
voidexampleE()
{
  eBlock
block = exampleE_getBlock();
  block();
}

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

选择 only works with ARC.

和example D类似, 这段代码会正常编译,运行时会崩溃。更糟的情况是,如果你不检查,测试时他可能运行正常,在项目中就会崩溃。

采用ARC block会被编译成一个自动释放的 NSMallocBlock.

总结

考虑一下关键点是什么?总是采用ARC嘛。采用ARC它总能运行正常. 如果你不采用ARC, 你最好这样做 block
= [[block copy] autorelease]
 。 这样强制编译器深拷贝成一个 NSMallocBlock。

哈哈,它当然远没有这么简单。苹果官网是这么提示的:

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.

原文译自http://blog.parse.com/2013/02/05/objective-c-blocks-quiz/。。不对之处各位大神请指正。新浪微博@WildCat李兴乐点击打开链接

Objective-C Blocks测试题与解析的更多相关文章

  1. PHP基础知识测试题及解析

      本试题共40道选择题,10道判断题,考试时间1个半小时 一:选择题(单项选择,每题2分): 1. LAMP具体结构不包含下面哪种(A ) A:Windows系统 B:Apache服务器 C:MyS ...

  2. Objective-C 与 C++ 的异同

    stackflow 上有同学提问"C++ 与 Objective-C 有什么异同?"楼下的提供的两个资料挺不错的. 其一是: Pierre Chatelier 写的 <Fro ...

  3. MIT jos 6.828 Fall 2014 训练记录(lab 5)

    源代码参见我的github: https://github.com/YaoZengzeng/jos File system perliminaries 我们开发的是一个单用户的操作系统,只提供了足够的 ...

  4. Cheatsheet: 2013 08.01 ~ 08.13

    Mobile Objective C Blocks: Summary, Syntax & Best Practices Android SDK: Create an Arithmetic Ga ...

  5. iOS 常见 Crash 及解决方案

    一.访问了一个已经被释放的对象 在不使用 ARC 的时候,内存要自己管理,这时重复或过早释放都有可能导致 Crash. 例子 NSObject * aObj = [[NSObject alloc] i ...

  6. 玩转webpack(二):webpack的核心对象

    欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 作者介绍:陈柏信,腾讯前端开发,目前主要负责手Q游戏中心业务开发,以及项目相关的技术升级.架构优化等工作. 前言 webpack 是一个强大的模 ...

  7. SoftwareEngineering.APIDesign.iOS

    API Design for iOS/Mac (Objective-c Edition) 1. UI Control Library API的设计 和已有组件保持一致(例如: 使用标准的API, 模型 ...

  8. C,OC,C++语言对比

    1.C与OC.C++的区别: C语言的特点:面向过程 1)C语言是结构化语言,层次清晰,调试和维护比较容易 2)表现能力和处理能力比较强,可直接访问内存的物理地址 3)c语言实现对硬件的编辑,c语言课 ...

  9. Clang:LLVM的C语言家族前端

    Clang:LLVM的C语言家族前端 Clang项目为LLVM 项目的C语言家族(C,C ++,Objective C / C ++,OpenCL,CUDA和RenderScript)中的语言提供了语 ...

随机推荐

  1. Oracle\MS SQL Server Update多表关联更新

    原文:Oracle\MS SQL Server Update多表关联更新 一条Update更新语句是不能更新多张表的,除非使用触发器隐含更新.而表的更新操作中,在很多情况下需要在表达式中引用要更新的表 ...

  2. C# Parse和Convert的区别分析(转)

    大家都知道在进行类型转换的时候有连个方法供我们使用就是Convert.to和*.Parse,但是疑问就是什么时候用C 什么时候用P 通俗的解释大家都知道: Convert 用来转换继承自object类 ...

  3. 通用Key-Value存储系统的存储管理策略解析

            Key-Value存储作为NoSQL存储的一种常见方式,提供了比SQL数据库更好的可扩展性和读写性能. 比方当前开源最热门的Memcached和Redis:淘宝的Tair.腾讯的Cme ...

  4. 【百度地图API】如何在地图上添加标注?——另有:坐标拾取工具+打车费用接口介绍

    原文:[百度地图API]如何在地图上添加标注?--另有:坐标拾取工具+打车费用接口介绍 摘要: 在这篇文章中,你将学会,如何利用百度地图API进行标注.如何使用API新增的打车费用接口. ------ ...

  5. 根据Unix哲学来编写你的HTML5 Websocket服务器来实现全双工通信

    websocketd代表WebSocket的守护进程 websocketd处理的是浏览器和服务器之间的WebSocket连接,它会启动你所指定的服务器端应用来对WebSockets进行处理,然后在浏览 ...

  6. SQL点滴19—T-SQL中的透视和逆透视

    原文:SQL点滴19-T-SQL中的透视和逆透视 透视 今天抽一点时间来看看透视和逆透视语句,简单的说就是行列转换.假设一个销售表中存放着产品号,产品折扣,产品价格三个列,每一种产品号可能有多种折扣, ...

  7. jQuery EasyUI API - Grid - DataGrid [原创汉化官方API]

    最近在学习jQuery EasyUI,发现中文的文档好少,部分文档不错但它是鸟语的,为了大家也为了自己学习吧,汉化做一下笔记. 有没有说清楚的,或者翻译不正确的地方还请大家谅解指出.. 由于工作时间原 ...

  8. CI框架 .htaccess 隐藏url在index.php解决方案

    CodeIgniter(下面简称"CI")是一款国外优秀的PHP轻量级MVC框架,它支持PHP4和PHP5.是开发中小型可拓展性需求高的Web应用程序的利器.眼下你所见到的这个博客 ...

  9. JS字符串数字互转

    JS是一种弱类型的脚本语言,为变量赋值是会自动转换为相应的类型,例如: var a = 1; alert(a + 1);//结果为2 自动识别为数字类型进行数学运算 var b = '1'; aler ...

  10. leetcode第十题--Regular Expression Matching

    Problem:Implement regular expression matching with support for '.' and '*'. '.' Matches any single c ...