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

In Objective-C (as of Xcode 7), the __block modifier for use with primitives is clearly explained in Stack Overflow such as here and by Apple here in the Blocks Programming Guide. Without the label, a copy of the primitive is captured and the original cannot be modified from within the block. With the label, no copy, and the original can be modified from within the block.
But for use with pointers to objects, the situation is not so well explained. Here Apple says either “a strong reference is made to self” or “a strong reference is made to the variable”. But then at the end of the page Apple says:
To override this behavior for a particular object variable, you can mark it with the __block storage type modifier.
What does “override this behavior” mean?
Further complicating things is that some posts on Stack Overflow talking about making a weak reference when calling an object from within a block.
I am not trying to establish an object. I just want to modify an existing object’s state from within a block. I believe the block is being called synchronously, within the same thread.
Imagine:
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 …
My questions:
How should that code be modified with __block modifier?
How should that code be modified with weak references?
What other issues apply to an object’s state modified from within a block?

First of all, the basic point of __block is the same for all types of variables (primitive variables, object-pointer variables, and all other variables) -- __block makes the variable shared between the outside scope and the scopes of the blocks that capture it, so that an assignment (=) to the variable in one scope is seen in all other scopes.
So if you don't use __block, if you assign to an object-pointer variable to point to another object outside the block after the block is created, the block won't see the assignment to the variable, and will still see it pointing to the object it was pointing to when the block was created. Conversely, inside the block you won't be able to assign to the variable. If you do use __block, then assignments to the variable to point to another object, either inside or outside the block, will be reflected in the other scopes.
Note that mutation of objects' state has nothing to do with assignment to variables. You mutate objects' state by calling a mutating method on a pointer to the object, or you can alter a field directly using a pointer to the object using the -> syntax. Neither of these involve assigning to a variable holding the pointer to the object. On the other hand, assigning to a variable holding a pointer to an object only makes the pointer point to another object; it does not mutate any objects.
The part you are reading about strong references and "override this behavior" has to do with the separate issue of memory management behavior of blocks under MRC only. Under MRC, there is no concept of variables being __strong or __weak like in ARC. When a variable of object-pointer type is captured by a block in MRC, it is by default captured as a strong reference (the block retains it, and releases it when the block is deallocated), because that is the desired behavior most of the time. If you wanted the block to not retain the captured variable, the only way to do that was to make it __block, which not only made the variable shared between the two scopes, but also made the block not retain the variable. So the two concepts were conflated in MRC.
In ARC, whether a block captures a variable strongly or weakly depends on the captured variable being __strong or __weak (or __unsafe_unretained), and is completely orthogonal with whether the variable is __block or not. You can have object-pointer variables that are __block without being weakly captured, or weakly captured without being __block, or both weakly captured and __block if you want.

You quote the somewhat dated Blocks Programming Topics, which says:
To override this behavior for a particular object variable, you can mark it with the __block storage type modifier.
That document dates back to the days of manual reference counting, back before ARC. In manual reference counting code you could use __block to avoid establishing a strong reference to objects referenced inside the block.
But this behavior has changed with ARC, as outlined in Transitioning to ARC Release Notes. We now use weak in those cases where we don't want to establish strong references to the objects referenced in the block. (You can use unsafe_unretained in special cases where you know the resulting dangling pointer isn't a problem.)
So, go ahead and use __block when dealing with fundamental types that you want to mutate inside the block. But when dealing with objects in blocks under ARC, the __block qualifier generally doesn't enter the discussion. The question is simply whether you want a strong reference or a weak one (or an unsafe, unretained one). And that's largely dictated by the object graph of your app, namely (a) whether you need weak/unretained reference to prevent strong reference cycle; or (b) you don't want want some asynchronously executing block to unnecessarily prolong the life of some object referenced in the block. Neither of those situations would appear to be the case here.

Related

When accessing properties, what is the different between dot syntax and "->" [duplicate]

This question already has answers here:
What is the difference between '->' (arrow operator) and '.' (dot operator) in Objective-C?
(3 answers)
Closed 8 years ago.
I have a block that uses a weak reference of itself to access properties inside the block. When accessing those properties, I use
__weak ViewController *weakSelf = self;
someBlock = ^{
ViewController *safeSelf = weakSelf;
weakSelf.someObject
safeSelf->someObject
}
When using weakself, what is the reason for using dot syntax and for the strong reference from the weak reference, to use -> syntax
The object->iVar syntax accesses the instance variable directly, without using the property.
You should forget you ever saw this, and never, ever use it (Until you get to the point where you understand this stuff cold, and find the .01% edge case where you need it.)
That syntax allows you to reach into another object and access it's instance variables directly, which is bad practice. Properties allow you to control access to an object's public interface, and maintain the encapsulation of the object.
The __weak weakSelf convention is for code blocks. Code blocks capture a strong reference to variables from their enclosing scope, and can cause a retain cycle, since your object has a strong reference to the block and the block has a strong reference to the object through the reference to self. By creating a weak variable weakSelf, you make the block's reference to the object that owns it weak, and avoid the retain cycle.
-> directly accesses the instance variable. weakSelf.someObject is equivalent to [weakSelf someObject].
You probably don't want to use -> for this unless you have a specific reason, like performance, or to skip KVO. Generally, it is preferred to use property access.
A side note: you should not use weakSelf for anything besides creating safeSelf. After that, you should get everything you need from safeSelf. (weakSelf can turn nil at any point if there are no longer strong references to the object.)
weakSelf.someObject
safeSelf->someObject
They are both silly. Having established a strong safeSelf in the first line of your block, you should make sure it is not nil and then use it exclusively, with normal property (dot) syntax so that you pass through the accessor method and get whatever benefits it has (which might include thread safety):
safeSelf.someObject
You definitely do not want to use ->. The concern here is that your reference to self might be nil - and using -> on a nil object is a disaster.

Is there an Objective-C property attribute that mimics the functionality of the __block keyword?

I want to make a property that allows a block to update its contents. For a typical variable (i.e. not auto-synthesized, etc), I would prefix the declaration with __block.
Is there a way to make a property that is able to be updated by a block?
Edit: Some answers say just to use the properties setter method. What I actually want to do is add objects to a mutable array, so I don't really want to create a new mutable array and set it back to the property using setProperty: or .property = each time. Is it possible to modify the property without all of these memory allocations?
__block is used to declare local variables that a block might want to change.
Neither are properties local variables, nor is there a need to change a variable when all you want to do is add something to a mutable array. The variable does not change, it's the object's state behind the variable that changes.
This isn't the right way to think about it. You want to modify an object, which has a property. So you capture the object in the block, and call its accessors (setFoo:) to modify the property.
EDIT: From the various edits, you may be confusing how ObjC objects work and how C++ works. ObjC only uses pointers to objects, seldom copies them, and lacks the concept of a const object (there are immutable objects, but it's just because they don't have mutators; you can't const a mutable object like you can in C++).
__block just means "this variable (not the object pointed to by it; this actual variable) should be passed by reference into the block rather than by value)." So when I say:
__block id foo;
this means that the foo pointer itself can be changed. It has nothing at all to do with whether the object pointed to by foo can be mutated. This makes no sense for a global or an ivar. ivars are implicitly struct fields. When you say _ivar inside a block, the compiler implicitly converts this to self->_ivar and then captures self. It does not capture _ivar (since that's just an offset into the self struct). It's better to do the same using accessors, since it's much more explicit what you're doing, and you can use __weak that way.
You use __block when you want to modify a variable within a block; in your case what you want to do is not modifying the variable(it will still point to the same NSMutableArray) but just sending a message to it(addObject:). You don't need __block for that.
There is no need to put anything into a #property declaration. since they can be accessed and modified by blocks without any trouble. According to the documentation:
Within the block object’s body of code, variables may be treated in
five different ways.
You can reference three standard types of variable, just as you would
from a function:
Global variables, including static locals
Global functions (which aren’t technically variables)
Local variables and parameters from an enclosing scope
Blocks also support two other types of variable:
At function level are __block variables. These are mutable within the
block (and the enclosing scope) and are preserved if any referencing
block is copied to the heap.
const imports.
The following rules apply to variables used within a block:
Global variables are accessible, including static variables that
exist within the enclosing lexical scope.
Parameters passed to the block are accessible (just like parameters to a function).
Stack (non-static) variables local to the enclosing lexical scope are
captured as const variables.Their values are taken at the point of
the block expression within the program. In nested blocks, the value
is captured from the nearest enclosing scope.
Variables local to the enclosing lexical scope declared with the
__block storage modifier are provided by reference and so are mutable.
Any changes are reflected in the enclosing lexical scope,
including any other blocks defined within the same enclosing lexical
scope.
Local variables declared within the lexical scope of the block,
which behave exactly like local variables in a function.Each
invocation of the block provides a new copy of that variable. These
variables can in turn be used as const or by-reference variables in
blocks enclosed within the block.

Having trouble understanding Objective-C Block Documentation

I'm currently having trouble understanding the fundamentals of Obj-C blocks and the __block storage type. From the following documentation:
http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/bxVariables.html#//apple_ref/doc/uid/TP40007502-CH6-SW6
I'm trying to understand the following paragraph and examples:
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.
The following examples illustrate the two different situations:
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);
});
To override this behavior for a particular object variable, you can mark it with the __block storage type modifier.
My questions:
How exactly is one example "accessed by reference" while the other one is accessed by variable? Why is localVariable "used by value?"
What does the doc mean by "a strong reference is made to self"? Which "self" is it referring to?
If I add the __block storage type to localVariable in the second example, am I wrong to assume that the block closes over the variable, so it keeps it around in heap until block is released? What other things are happening?
Thank you!
How exactly is one example "accessed by reference" while the other one is accessed by variable? Why is localVariable "used by value?"
One way to understand this is the following:
when you use a local variable in a block defined in the method, what happens is that the content of the variable is copied in some block private memory, so that it is available when the block is executed (after the method exits); in this sense we may talk of accessed "by value" (as in: the value is copied); syntactically the compiler doesn't know what the content of localVariable refers to, so its values is treated as such;
when directly accessing instanceVariable in a block defined within a method of a class, the compiler knows that we are accessing the same object that is executing the method and there is not need to copy anything, since the object has a longer lifetime than the method where the block is found; but we need to ensure that the object is still there when the block is executed, so we get a strong reference to it.
Now, as to the use of "by reference": in the first case, you get a copy of the reference to the class member: if you could change its value (but you can't, because the compiler forbids it), you were just modifying a block private copy, so the original object is not affected.
In the second case, you can modify the value of instanceVariable (like in: it was nil and you allocate an object referred through it) and this will affect the object that executed the method were the block is defined.
What does the doc mean by "a strong reference is made to self"? Which "self" is it referring to?
self is the object which is currently executing the method where the block is found. that a strong reference is made only means (in ARC parlance) that the retain count of the object is incremented (to make sure some other entity cannot cause it to be deallocated by releasing it).
If I add the __block storage type to localVariable in the second example, am I wrong to assume that the block closes over the variable, so it keeps it around in heap until block is released? What other things are happening?
Using __block makes the variable be always accessed "by reference", so you can modify them.
This is how they are handled:
__block variables live in storage that is shared between the lexical scope of the variable and all blocks and block copies declared or created within the variable’s lexical scope. Thus, the storage will survive the destruction of the stack frame if any copies of the blocks declared within the frame survive beyond the end of the frame (for example, by being enqueued somewhere for later execution). Multiple blocks in a given lexical scope can simultaneously use a shared variable.
As an optimization, block storage starts out on the stack—just like blocks themselves do. If the block is copied using Block_copy (or in Objective-C when the block is sent a copy), variables are copied to the heap. Thus, the address of a __block variable can change over time.

IOS block pointer copy issue.

See the following animation execution block, how does the UI control pointer clickButton copy from stack to heap? By reference (retain) or just copy pointer value (not deep copy)?
Thanks in advance.
[UIView animateWithDuration:10.0 animations:^(void){
clickButton.alpha = 1.0; // clickButton is class variable.
}];
When a block is copied (which it is in this case), any objective-c objects that are referenced by the block are retained (and then released when the block is dealloc'd).
In this case, if clickButton was a local variable outside the block, it would be retained inside the block. However, you said it was a "class variable", which I assume you mean it's an instance variable. Because of that, the block actually retains self, since the reference to the ivar is really an implicit lookup of the ivar within self.
In MRR (non-ARC) code, any obj-c objects which are marked with the __block storage qualifier are actually not retained by the capturing block. This is for technical reasons, but it has been taken advantage of by many people. However, in ARC code, __block-qualified variables do get retained (and released) by the block. If you need a non-retained object under ARC, you can use __unsafe_unretained instead. However, in ARC code, weak references typically solve the same problem that __unsafe_unretained variables do, but much more safely.
Since the block here has a temporary lifetime (it only lives for the duration of the animation), there's no problem with retaining self. However, for more permanent blocks whose lifetime are actually tied to that of self (e.g. they're stored in an ivar, or on an object that self owns), you should be careful not to introduce a retain cycle. If you're using ARC, weak references can help you here.

Clarification on Apple's Block Docs?

I am working through some retain-cycle issues with blocks/ARC, and I am trying to get my head around the nuances. Any guidance is appreciated.
Apple's documentation on "Blocks and Variables" (http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/bxVariables.html) says the following:
If you use a block within the implementation of a method, the rules
for memory management of object instance variables are more subtle:
If you access an instance variable by reference, self is retained; If
you access an instance variable by value, the variable is retained.
The following examples illustrate the two different situations:
dispatch_async(queue, ^{
// instanceVariable is used by reference, self is retained
doSomethingWithObject(instanceVariable);
});
id localVariable = instanceVariable;
dispatch_async(queue, ^{
// localVariable is used by value, localVariable is retained (not self)
doSomethingWithObject(localVariable);
});
I find this explanation confusing.
Is this appropriate use of the "by value" / "by reference" terminology? Assuming that these variables are of the same type (id), it seems like the distinguishing characteristic between them is their scope.
I do not see how self is being referenced in the "by reference" example? If an accessor method were being used, (e.g. - below), I could see self being retained.
doSomethingWithObject(self.instanceVariable);
Do you have any guidance on when one might want to do things one way or the other?
If conventional wisdom is to utilize the "by value" variables, it seems like this is going to result in a lot of additional code for additional variable declarations?
In a circumstance where nested blocks are coming into play, it seems like it may be more maintainable to avoid declaring the blocks inside of each other as one could ultimately end up with a potpourri of unintentionally retained objects?
Think of the case of using instanceVariable as an equivalent of writing self->instanceVariable. An instance variable is by definition "attached" to the self object and exists while the self object exists.
Using instanceVariable (or self->instanceVariable) means that you start from the address of self, and ask for an instance variable (that is offset of some bytes from the self object original address).
Using localVariable is a variable on its own, that does not rely on self and is not an address that is relative to another object.
As the blocks capture the variables when they are created, you typically prefer using instance variables when you mean "when the block is executed, I want to get the value of the instance variable at the time of the execution" as you will ask the self object for the value of the instance variable at that time (exactly the same way as you would call [self someIVarAccessorMethod]). But then be careful not to create some retain cycles.
On the other hand, if you use localVariable, the local variable (and not self) will be captured when the block is created, so even if the local variable changes after the block creation, the old value will be used inside the block.
// Imagine instanceVariable being an ivar of type NSString
// And property being a #property of type NSString too
instanceVariable = #"ivar-before";
self.property = #"prop-before";
NSString* localVariable = #"locvar-before";
// When creating the block, self will be retained both because the block uses instanceVariable and self.property
// And localVariable will be retained too as it is used directly
dispatch_block_t block = ^{
NSLog(#"instance variable = %#", instanceVariable);
NSLog(#"property = %#", self.property);
NSLog(#"local variable = %#", localVariable);
};
// Modify some values after the block creation but before execution
instanceVariable = #"ivar-after";
self.property = #"prop-after";
localVariable = #"locvar-after";
// Execute the block
block();
In that example the output will show that instanceVariable and self.property are accessed thru the self object, so self was retained but the value of instanceVariable and self.property are queried in the code of the block and they will return their value at the time of execution, respectively "ivar-after" and "prop-after". On the other hand, localVariable was retained at the time the block was created and its value was const-copied at that time, so the last NSLog will show "locvar-before".
self is retained when you use instance variables or properties or call methods on self itself in the code of the block. Local variables are retained when you use them directly in the code of the block.
Note: I suggest you watch the WWDC'11 and WWDC'12 videos that talks about the subject, they are really instructive.
Is this appropriate use of the "by value" / "by reference" terminology? It's at least analogous to the typical use. Copying a value to a local variable is like copying a value onto the stack; using an ivar is like passing a pointer to a value that's stored somewhere else.
I do not see how self is being referenced in the "by reference" example? When you use an instance variable inside a method, the reference to self is implied. Some people actually write self->foo instead of foo to access an ivar just to remind themselves that foo is an ivar. I don't recommend that, but the point is that foo and self->foo mean the same thing. If you access an ivar inside a block, self will be retained in order to ensure that the ivar is preserved for the duration of the block.
Do you have any guidance on when one might want to do things one way or the other? It's useful to think in terms of the pass by reference/pass by value distinction here. As AliSoftware explained local variables are preserved when the block is created, just as parameters passed by value are copied when a function is called. An ivar is accessed through self just as a parameter passed by reference is accessed through a pointer, so its value isn't determined until you actually use it.
it seems like this is going to result in a lot of additional code for additional variable declarations? Blocks have been a feature of the language for a while now, and I haven't noticed that this is a problem. More often, you want the opposite behavior: a variable declared locally that you can modify within a block (or several blocks). The __block storage type makes that possible.
it seems like it may be more maintainable to avoid declaring the blocks inside of each other as one could ultimately end up with a potpourri of unintentionally retained objects? There's nothing wrong with letting one or more blocks retain an object for as long as they need it -- the object will be released just as soon as the blocks that use it terminate. This fits perfectly with the usual Objective-c manual memory management philosophy, where every object worries only about balancing its own retains. A better reason to avoid several layers of nested blocks is that that sort of code may be more difficult to understand than it needs to be.

Resources