关于ios:当从Objective-C中的块中访问时,对象是否需要(a)`__block`修饰符或(b)弱引用?

Does object need (a) `__block` modifier or (b) weak reference, when accessed from within a block in Objective-C?

在Objective - C的(7)__blockXcode),改性剂是用在具有明确的解释primitives堆栈溢出,如用在这里的苹果块和编程指南。在没有标签,捕获和复制的原始是从原来的不能在一块。在与标签,复制,和原来可以从在一块。

但使用与对象分到的情况是不好的,操作系统的解释。苹果公司说,"这里是指参考自强"或"强"的标准是可变的。然后,在尽头的页面说:苹果

To override this behavior for a particular object variable, you can mark it with the __block storage type modifier.

是什么意思"重写这个行为"?

那是一个进一步的complicating事情谈制作在线栈溢出时调用对象从一个弱参考在一块。

我不想建立一个对象。我只是想修改一个对象的状态,从现有的在一块。我相信在被称为是一个同步块,在相同的线程。

想象一下:

1
2
3
4
5
6
7
8
9
10
11
12
Clicker* myClicker = [[Clicker alloc] init] ;

// Declare a block.
void (^myBlock)( );

// Populate the block.
myBlock = ^ void ( ) {
    [myClicker click] ; // Updating some state in that object, such as incrementing a counter number or adding an element to a collection.
};

// Call `myBlock` synchronously (same thread) from some other code.
…  // … invokes `myBlock` repeatedly …

我的问题:

  • 那应该怎么改性剂是与__block代码?

  • 那应该怎么改性与弱引用的代码是什么?

  • 另一问题是适用于对象的状态,从中一块?


您引用了一些过时的块编程主题,其中说:

To override this behavior for a particular object variable, you can mark it with the __block storage type modifier.

该文件可追溯到人工参考计数的日期,早在ARC之前。在手动引用计数代码中,可以使用__block来避免对块内引用的对象建立强引用。

但这种行为随着ARC的变化而改变,如过渡到ARC发行说明中所述。我们现在在不希望建立对块中引用的对象的强引用的情况下使用weak。(您可以在特殊情况下使用unsafe_unretained,在这种情况下,您知道生成的悬空指针不是问题。)

所以,继续使用__block,当处理您想要在块内变异的基本类型时。但在处理弧下块中的对象时,__block限定符一般不进入讨论。问题很简单,你是想要一个有力的参考,还是一个软弱的参考(或一个不安全的,不可靠的参考)。这在很大程度上取决于应用程序的对象图,即(a)是否需要弱引用/不包含引用来防止强引用循环;或(b)不希望某些异步执行的块不必要地延长块中引用的某些对象的寿命。这两种情况在这里都不会出现。


首先,对于所有类型的变量(原始变量、对象指针变量和所有其他变量),__block的基本点是相同的——__block使变量在外部作用域和捕获它的块的作用域之间共享,从而可以看到对一个作用域中变量的赋值(=)在所有其他范围内。

因此,如果不使用__block,如果在创建块后为对象指针变量赋值,以指向块外的另一个对象,则块将看不到对变量的赋值,仍将看到它指向创建块时所指向的对象。相反,在块内部,您将无法分配给变量。如果确实使用__block,那么对变量的赋值将反映在其他作用域中,以指向块内或块外的另一个对象。

注意,对象状态的变化与变量的赋值无关。您可以通过在指向对象的指针上调用一个可变方法来改变对象的状态,也可以使用->语法直接使用指向对象的指针来改变字段。这两种方法都不涉及为保存对象指针的变量赋值。另一方面,给一个变量赋一个指向对象的指针只会使指针指向另一个对象;它不会改变任何对象。

您正在阅读的关于强引用和"重写此行为"的部分只与MRC下块的内存管理行为的单独问题有关。根据MRC,在ARC中没有变量是__strong__weak的概念。当一个对象指针类型的变量被MRC中的一个块捕获时,它在默认情况下被捕获为一个强引用(该块保留它,并在释放该块时释放它),因为这是大多数情况下需要的行为。如果希望块不保留捕获的变量,唯一的方法是使它成为__block,这不仅使变量在两个作用域之间共享,而且使块不保留变量。所以这两个概念在MRC中被融合了。

在ARC中,一个块是强捕获变量还是弱捕获变量取决于捕获的变量是__strong__weak__unsafe_unretained,并且与该变量是否为__block完全正交。如果需要的话,对象指针变量可以是__block,而不被弱捕获,或者是被弱捕获而不被__block,或者是同时被弱捕获和__block