Reputation: 889
Refer to Assign a variable inside a Block to a variable outside a Block
It says it should add __block
to the variable, but I see some codes in Google Youtube sample code for objc here https://code.google.com/p/google-api-objectivec-client/source/browse/trunk/Examples/YouTubeSample/YouTubeSampleWindowController.m
from line 279 to 290:
_channelListTicket = [service executeQuery:query
completionHandler:^(GTLServiceTicket *ticket,
GTLYouTubeChannelListResponse *channelList,
NSError *error) {
// Callback
// The contentDetails of the response has the playlists available for
// "my channel".
if ([[channelList items] count] > 0) {
GTLYouTubeChannel *channel = channelList[0];
_myPlaylists = channel.contentDetails.relatedPlaylists;
}
Why the variable _myPlaylists
can be assigned without adding __blocks
first ?
Upvotes: 1
Views: 1128
Reputation: 100622
To expand on dasblinkenlight's answer: it all comes down to the heap versus the stack.
Speaking inexactly:
The heap is the area of memory from which dynamic allocation occurs. Every time you create a new object via alloc
or similar, make a C call to malloc
or one of its kin, or use the analogous methods in Core Foundation or elsewhere, the storage lives on the heap. It's there until someone returns it. Mere program flow doesn't affect items on the heap.
The stack is the area of memory used to manage program flow. So it's where local variables go. It also contains, in effect, a record of all the calls made to descend down to wherever the program is now — every method or function call results in a tiny bit of the stack being set aside for that call. It's a stack so it grows in one direction only. When a method returns its part of the stack is implicitly returned to the system for reuse. If your program crashes then that list of who called whom is a stack trace, showing the current state of the stack.
Blocks capture state. State includes things on the stack and on the heap. The blocks may exist long after that part of the stack has been returned. They therefore have to do work if you want a variable that lives on the stack to be modifiable — specifically, it can't actually live on the stack. __block
achieves that. Items are not marked with it by default because it's slower.
So finally to get to your actual question: self
has been allocated on the heap. Therefore its lifetime is not directly linked to program flow. Therefore the block can capture it by reference and modify its state later. No problems. _myPlaylists
is just an instance variable of self
.
That would not be true of a variable on the heap, such as a local variable. The block could not be sure its storage would still be legal to access later. Someone else might be using the storage for something else by then. Capturing the current value is no problem as the storage is still safe to access when the block is created but you'd have to use __block
to mark that variable to use storage on the heap rather than the stack if you wanted to be able safely to write a new value to it later.
Upvotes: 2
Reputation: 726579
Why the variable
_myPlaylists
can be assigned without adding__block
first?
Because it is not a local variable in your function. Only the locals that you plan to assign need a __block
designation. Instance variables* are referenced through self
; they never need to be marked with __block
.
*In the sample code that you link _myPlaylists
is an instance variable declared in the implementation block on line 49.
Upvotes: 6