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. linux_ubuntu12.04 安装 svn

    sudo apt-get install subversion sudo mkdir /home/svn sudo svnadmin create /home/svn/repository cd /h ...

  2. Cocos2d-x之MenuItem

    ***************************************转载请注明出处:http://blog.csdn.net/lttree************************** ...

  3. oracle处理节点之间的父子关系

    通常当与树的结构之间的关系处理,这是一个很复杂的事情,我们可以通过程序代码去逐层遍历父或子节点,这样做的缺点是很明显,效率不高,操作复杂性是比较大的.而当我们使用Oracle当数据库,我们可以有一个简 ...

  4. 搜集朋友写的几篇Android Elf相关的文档

    对android elf的资料学习,多数是在看雪找的资料,另一部分朋友的研究,当然,给他们提议过整理成一系列文章,只是大家工作都太忙,也都没顾上,这里简单整理放上一些pdf的资料,有兴趣的朋友能够看看 ...

  5. jquery 仅仅读

    大家都理解这是什么,正常的写法例如以下: if (status == true) { $("#minDelistStr").val(totalAmount);// 去掉首部的&qu ...

  6. IOS启动其他应用程序

    从app1打开app2.主要的思路就是,能够为app2定义一个URL,在app1中通过打开这个URL来打开app2,在此过程中.能够传送一些參数. 在app1的代码中打开刚才定义的URL.代码例如以下 ...

  7. 2014阿里巴巴研发project师暑期实习生面试经验

    2014阿里巴巴研发project师暑期实习生面试经验 作者:林子 Blog:  http://blog.csdn.net/u013011841 时间:2014年8月 出处:http://blog.c ...

  8. 创建GitHub技术博客

    创建GitHub技术博客全攻略 githubio技术博客网站生成 说明: 首先,你需要注册一个 github 账号,最好取一个有意义的名字,比如姓名全拼,昵称全拼,如果被占用,可以加上有意义的数字.本 ...

  9. Impala源代码分析---1

    2.Impala源代码分析 參考链接:http://www.sizeofvoid.net/wp-content/uploads/ImpalaIntroduction2.pdf 本章開始进入源代码分析阶 ...

  10. MySQL引擎的相关知识

    MySQL数 据库引擎取决于MySQL在安装的时候是如何被编译的.要添加一个新的引擎,就必须重新编译MYSQL.在缺省情况下,MYSQL支持三个引 擎:ISAM.MYISAM和HEAP.另外两种类型I ...