I had the same sorts of questions when I saw that line: channel = obj;
In fact it got me quite distracted from the lesson.
On pg 493 it says "Thus, a block has access to all of the local variables of the method, arguments passed to the method, and instance variables that belong to the object running the method."
On the next page, it says “… the values of the captured variables remain the same …”, and “… its arguments can change each time it is called.” The issue of local vs instance variables is not mentioned there.
We saw proof that local variables are captured when the block is defined, and that arguments are passed when the block is invoked. What about instance variables? Apparently they are not captured (after all the compiler really has no choice but to capture local variables, because they will vanish when the method that constructs the block is popped off the stack, but the object that created the block has to be kept). They appear to be completely accessible by the block at the time it executes (as if they were global variables). The ‘channel = obj;’ statement is proof enough. However, I went back into Blocky from Chapter 28, and did an experiment.
I created an instance variable in BNRAppDelegate.h:
And synthesized it in BNRAppDelegate.m:
Then when we assigned values to “multiplier” I also assigned the same values to “factor”
int multiplier = 3;
factor = 3;
multiplier = 100;
factor = 100;
Finally, I ran Blocky switching the return value between
When I used multiplier, the result was 21. When I used factor, the result was 700. The block was executed later due to the Operation Queue stuff, so, we proved that the post-block-definition value of factor was used.
This may have answered another question that has been bugging me. C has always had the concept of a pointer to a function, and the way that you declare them looks just like a block declaration (except with a * instead of a ^). So why did objective C create the concept of blocks, instead of just using pointers to functions. I now suspect the answer is that blocks have a concept of the “self” pointer, which makes this question more profound than the nit-picky issue that it initially appeared to be. The direct accessibility within a block at execution time of the instance variables of the object within which the block was defined is (I suspect) a big part of what makes a block special.