I am somewhat new to blocks and need some help. I want to store a block in an NSDictionary
and execute said block when it is accessed based off its key
. Here is what I have so far as an example.
NSDictionary *blocks = [NSDictionary dictionaryWithObjectsAndKeys:
^{NSLog(@"Log Block 1");}, @"Block1",
^{NSLog(@"Log Block 2");}, @"Block2",
nil];
I then enumerate through the dictionary by using keyEnumerator
. I know the block is being stored properly because I call NSLog(@"%@", [blocks objectForKey:key]);
during the enumeration and get <__NSGlobalBlock__: 0x100003750>
. So I know I can access it but how can I execute it at this point?
Try this:
void(^myAwesomeBlock)() = [blocks objectForKey:key];
myAwesomeBlock();
I noticed, though, that when subsequent calls are made to each block it returns the same information as when it was first executed rather than including anything that may have changed since. Is there a way to make it execute each time its called rather than return the original information?
Refer to the documentation on Blocks, specifically the section entitled Types of Variable:
The following rules apply to variables used within a block:
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. These are discussed in more detail in “The __block Storage Type.”
You need to cast:
id bar = [blocks objectForKey:@"Block1"];
((void(^)())bar)();