سؤال

Apple documentation on this matter states:

When a block is copied, it creates strong references to object variables used within the block. If you use a block within the implementation of a method:

If you access an instance variable by reference, a strong reference is made to self;

If you access an instance variable by value, a strong reference is made to the variable.

and there is code example:

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);

});

But to me it makes no sense. How can you access instance variable by value? Don't you always access it via reference? Be it self.myVariable or just id newName = self.myVariable, it is always by reference.

Then this example is not too clear what they mean. Why is in first case self retaind and in second case not? It's not used anywhere, so why would block capture it?

هل كانت مفيدة؟

المحلول

When you use an instance variable, the compiler turns what you see as the ivar name into self->iVar, and that's what the block uses. You can even do this in your code - try accessing something with self-> prepended.

EDIT: So in the first case, the block captures self, because it needs it to access instanceVariable, as in self-> instanceVariable. Thus, it will use whatever the value is when the block finally executes. Since self is an object, it gets retained.

In the second case, a temporary variable (object or not) is assigned the current value of self-> instanceVariable, whatever it is at that moment. When the block captures localVariable, it retains the object, and just after the dispatch_async call, ARC releases localVariable, so the block now is the only thing retaining localVariable. From then on, the class can change the instance variable and it will have no affect on whatever the block captured (one exception - if the object is a mutable object, then the block will use whatever the contents are when it runs - the reason to NOT to use mutable objects in this situation, but to use a non-mutable copy.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top