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. 求解决!!!SystemVerilog于ModelSim在编译和执行

    我们正在学习SV流程,样品执行书.. 功能:函数返回数组. Code1: /*书上提供的样例.存在错误,不可执行 function void init(ref int f[5], int start) ...

  2. CocoaPods 建立私有仓库

    CocoaPods是iOS,Mac下优秀的第三方包管理工具,类似于java的maven,给我们项目管理带来了极大的方便. [个人或公司在开发过程中,会积累很多可以复用的代码包,有些我们不想开源,又想像 ...

  3. 严重:IOException while loading persisted sessions:java.io.EOFException.

    1.错误叙述性说明 严重:IOException while loading persisted sessions:java.io.EOFException. java.io.EOFException ...

  4. C# 之 托付

    托付(delegate)     托付是一种能够把引用存储为函数的类型.托付也能够看成是一种数据类型,能够用于定义变量,但它是一种特殊的数据类型,它所定义的变量能接受的数值仅仅能是一个函数,更确切的说 ...

  5. Github资源汇集

    Github资源汇集 突然发现申请博客园已经两年有余,没有发表过一篇文章,十分惭愧.言归正传,先分享一下两年来收集的部分编程资源,大部分为Github上的项目.虽然网上这样的分享已不在少数,但不如我理 ...

  6. Linux忘记rootpassword

    我们常常会碰到忘记rootpassword的情况,以下是解决之道,  此方法使用绝大多数的Linux发行版:  1. 首先进入grub  2. 在须要编辑的入口处,按下e,在quite后增加     ...

  7. SQL点滴20—T-SQL中的排名函数

    原文:SQL点滴20-T-SQL中的排名函数 提到排名函数我们首先可能想到的是order by,这个是排序,不是排名,排名需要在前面加个名次序号的,order by是没有这个功能的.还可能会想到ide ...

  8. 《Shell十三问》笔记(上)

    <shell十三问>是网中人前辈首发在CU论坛上对SHELL的一些整理,非常值得一读 注:笔记的标号非问题标号,而是知识点的标号.本篇笔记记录的是1-10问的知识点 (1)IFS:Shel ...

  9. css-fixed兼容写法

    解决IE6中fixed闪动问题(效果稍微好一点,不能完全解决闪动问题) *{background-image:url(about:blank);background-attachment:fixed; ...

  10. 【转】Android Application 对象介绍

    What is Application Application和Activity,Service一样是android框架的一个系统组件,当android程序启动时系统会创建一个 application ...