Objective-C 块文档理解困难

7
我目前在理解Obj-C块和__block存储类型基础方面遇到了困难。以下是官方文档: http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/bxVariables.html#//apple_ref/doc/uid/TP40007502-CH6-SW6 我试图理解以下段落和示例: 当块被复制时,会对块中使用的对象变量创建强引用。如果你在方法实现中使用一个块:
如果通过引用访问实例变量,则会对self创建一个强引用; 如果通过值访问实例变量,则会对该变量创建一个强引用。 以下示例说明了两种不同的情况:
dispatch_async(queue, ^{
    // instanceVariable is used by reference, a strong reference is made to self
    doSomethingWithObject(instanceVariable);
});

id localVariable = instanceVariable;
dispatch_async(queue, ^{
    /*
      localVariable is used by value, a strong reference is made to localVariable
      (and not to self).
    */
    doSomethingWithObject(localVariable);
});

要覆盖特定对象变量的行为,您可以使用__block存储类型修饰符标记它。

我的问题:

  1. 一个例子如何通过引用访问,而另一个例子是通过变量访问的?为什么localVariable“按值使用”?
  2. 文档中的“强引用是对self的引用”,是指哪个“self”?
  3. 如果我在第二个示例中向localVariable添加__block存储类型,那么我是否错误地假设该块封闭了该变量,因此在堆中保留它直到块被释放?还有其他事情发生了吗?

谢谢!

1个回答

6
第一个问题的答案是:一个例子是通过引用访问的,而另一个例子是通过变量访问的。为什么localVariable是“按值使用”的?当你在方法中定义块时使用局部变量时,发生的情况是将变量的内容复制到某个块私有内存中,以便在执行块时(方法退出后)可用;从这个意义上说,我们可以谈论通过“值”访问(例如:值被复制)。语法上,编译器不知道localVariable所引用的内容,因此它的值被视为这样处理。直接在类的方法中访问instanceVariable时,编译器知道我们正在访问执行该方法的同一对象,并且不需要复制任何内容,因为对象的寿命比找到块的方法更长;但是我们需要确保在执行块时仍然存在该对象,因此我们对其进行了强引用。
第二个问题的答案是:文档中的“self”是指当前执行包含该块的方法的对象。强引用只是表示(在ARC术语中),该对象的保留计数已增加(以确保某些其他实体不能通过释放它来使其被解除分配)。
第三个问题的答案是:使用__block使变量始终通过引用访问,因此您可以修改它们。这是它们的处理方式。
__block变量存储在变量的词法作用域和所有在词法作用域中声明或创建的块及块副本之间共享的存储中。因此,如果块的任何副本在栈帧结束后仍然存在(例如被排队等待以供稍后执行),则该存储将在栈帧被销毁后仍然存在。给定词法作用域中的多个块可以同时使用共享变量。
为了优化,块存储通常初始存储在堆栈上,就像块本身一样。如果使用Block_copy(或在Objective-C中发送副本时),则将变量复制到堆上。因此,__block变量的地址可能会随时间而改变。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接