I'm pretty new to using blocks. I'm wondering if there is a way to add code dynamically to a block? A mutable block if you will.
-
Not quite. But you can try embedding a scripting engine if you wish, JavaScript core or Lua are good. – Dec 28 '12 at 21:42
-
dynamically making closures is not exactly easy... – CodaFi Dec 28 '12 at 21:43
2 Answers
This is not quite what it sounds like you want, but it achieves a similar result if not quite the same one: Having a __block NSMutableArray
of blocks to be called sequentially from within an outer block.
A silly demo:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
@autoreleasepool {
__block NSMutableArray *subblocks = [NSMutableArray array];
void (^blockWithBlocks)(void) = ^{
NSLog(@"%s: in blockWithBlocks()", __PRETTY_FUNCTION__);
for (void (^subblock)(void) in subblocks) {
subblock();
}
};
for (int i = 0; i < 3; i++) {
void (^subblock)(void) = ^{
NSLog(@"%s: in subblock %d", __PRETTY_FUNCTION__, i);
};
[subblocks addObject:subblock];
}
blockWithBlocks();
}
return 0;
}
Note that the requirements for copying blocks under ARC have been in flux. Previously it would have been necessary to write [subblocks addObject:[subblock copy]];
rather than simply [subblocks addObject:subblock];
Under the current semantics described in the clang documentation
With the exception of retains done as part of initializing a __strong parameter variable or reading a __weak variable, whenever these semantics call for retaining a value of block-pointer type, it has the effect of a Block_copy. The optimizer may remove such copies when it sees that the result is used only as an argument to a call.
the only times that it is necessary to copy a block to be sure that it is no longer on the stack is when the block is being passed as an argument to a function/method that has a __strong
parameter variable and when the block is being read from a __weak
variable.

- 4,533
- 1
- 23
- 32
What do you mean "add code dynamically to a block"? How is that different from simply making a new block from the "code" and the original block?
If the difference is that you want to have a reference to a block and have its behavior change without having to assign a new block to that reference, then you can have the block capture mutable state, where the mutable state could contain the block(s) to call, which you can then change, like what @NateChandler suggests.
If the difference is that is that you can choose between several different pieces of "code", so you cannot hard-code it at the place you are creating the block, then you can just make the "pieces of code" into blocks and select the right block to put into the new block.

- 119,665
- 29
- 163
- 224