我可以将^块存储在字典或数组中吗?
我需要收听一个服务器通知,我需要提供一个块来处理通知,在我的项目中,几个视图控制器都希望听到通知,所以我做了一个通用的通知管理器,它有自己的块用于处理服务器通知,它有一个委托数组,所以在管理器的块中:
- (^)(NSString *message){
for (delegate in allDelegates)
{
delegate.handlerBlock(message);
}
}
但是我可以在一个集合中存储块吗?
答案 0 :(得分:12)
您可以将对象存储到集合中。但要注意范围:当它们被排除在功能范围之外时复制它们。这是你的情况,因为你将它们存储在一个数组中。
[NSArray arrayWithObject:
[[^{ NSLog(@"block 1"); } copy] autorelease],
[[^{ NSLog(@"block 2"); } copy] autorelease], nil]
在ARC上,你仍然需要告诉它你绝对需要复制你的块。它应该在释放数组时释放块。
[NSArray arrayWithObject:
[^{ NSLog(@"block 1"); } copy],
[^{ NSLog(@"block 2"); } copy], nil]
答案 1 :(得分:5)
块的特殊之处在于,在大多数情况下应该保留其他对象时应该复制它们。正如您现在必须阅读的那样,这是因为块从堆栈开始(“堆栈块”),并且仅在定义它们的本地范围内有效。复制堆栈块会为您提供堆块,并且像普通对象一样具有动态生命周期。复制堆块会简单地保留它,因此当你需要将块保持更长时间时,复制块总是正确的。
现在,带有块参数的函数通常负责根据需要复制块。因此,在将块传递给这些函数时,您不需要做任何特殊操作。但是,在这种情况下,您将块传递给[NSArray arrayWithObject:]
,它接受一个普通的对象参数。因为它不接受块参数,所以它不知道复制参数,所以它只会保留它。因此,当您将块传递给采用普通对象参数的方法时,您需要先将其复制。
答案 2 :(得分:1)
如果你阅读了非常好的文章here,你会发现如何做到这一点。并特别注意那里提到的“将它们从堆栈中复制出来”这个成语。