我对使用块很陌生。我想知道是否有办法将代码动态添加到块中?如果你愿意,一个可变块。
2 回答
这听起来并不像您想要的那样,但如果不是完全相同的话,它也会获得类似的结果:__block NSMutableArray
从外部块中顺序调用一个块。
一个愚蠢的演示:
#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;
}
请注意,在 ARC 下复制块的要求一直在变化。以前,有必要在clang 文档 中描述的当前语义下编写[subblocks addObject:[subblock copy]];
而不是简单地编写[subblocks addObject:subblock];
除了作为初始化 __strong 参数变量或读取 __weak 变量的一部分完成的保留之外,每当这些语义要求保留块指针类型的值时,它都具有 Block_copy 的效果。当优化器发现结果仅用作调用的参数时,它可能会删除此类副本。
唯一需要复制一个块以确保它不再在堆栈上的情况是,当该块作为参数传递给具有__strong
参数变量的函数/方法时,以及从该块被读取时一个__weak
变量。
你是什么意思“动态添加代码到块”?这与简单地从“代码”和原始块创建一个新块有什么不同?
如果不同之处在于您希望获得对块的引用并更改其行为而不必为该引用分配新块,那么您可以让块捕获可变状态,其中可变状态可以包含块(s ) 调用,然后您可以更改它,就像@NateChandler 建议的那样。
如果不同之处在于您可以在几个不同的“代码”之间进行选择,因此您不能在创建块的地方对其进行硬编码,那么您可以将“代码”变成块并选择正确的块放入新块。