Graphics Programs Reference
In-Depth Information
counter += 2;
NSLog(@"Counter now at %d", counter);
};
plusOne(); // prints 1
plusTwo(); // prints 3
plusOne(); // prints 4
Additionally, if counter is modified after the block is defined, the value within the
block is also changed:
__block int counter = 0;
void (^plusOne)(void) = ^{
counter++;
NSLog(@"Counter now at %d", counter);
};
counter = 25;
plusOne(); // prints 26
When capturing a pointer to an object, you can always change the properties of that ob-
ject, but you cannot change what object the pointer points to. When declaring a pointer
with the __block modifier, you can change the pointer to point at another object within
the block:
NSString *string1 = @"Bar";
__block NSString *string2 = @"Bar";
void (^block)(void) = ^{
string1 = @"Foo"; // This is ILLEGAL
string2 = @"Foo"; // This is OK
};
Finally, one last tidbit of knowledge. When you allocate a block, it is created on the stack.
This means that, even if you were to keep a strong reference to it, calling it later would
result in a crash because the memory would be destroyed as soon as you leave the method
in which it was defined.
The way around this disaster is to send the message copy to a block. When you copy a
block, the block is moved to the heap, where storage outlasts the current stack frame. (You
probably noticed that the equation property of BNRExecutor in this exercise had the
copy attribute. That does the same thing.) If a block is already in the heap, sending it the
message copy just adds another strong reference to it instead of making another copy of
the block.
Before ARC, forgetting to copy a block was a big deal and created hard-to-find bugs when
a block had a strong reference but had also been deallocated. With the advent of ARC, the
compiler now knows a lot about blocks. So, even if you just assign a block to a strong
Search WWH ::




Custom Search