12

我可以将 ^block 存储在字典或数组中吗?

我需要收听一个服务器通知,我需要提供一个块来处理通知,在我的项目中,几个视图控制器都想听到通知,所以我制作了一个通用通知管理器,它有自己的块来处理服务器通知,它有一个代表数组,所以在经理的块中:

- (^)(NSString *message){
    for (delegate in allDelegates)
    {
        delegate.handlerBlock(message);
    }
}

但是我可以将块存储在集合中吗?

4

3 回答 3

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]
于 2012-10-24T07:38:45.300 回答
5

块的特殊之处在于,在大多数情况下应该保留其他对象时应该复制它们。正如您现在必须阅读的那样,这是因为块从堆栈开始(“堆栈块”),并且仅在定义它们的本地范围内有效。复制堆栈块会为您提供一个堆块,它将像普通对象一样具有动态生命周期。复制堆块只会保留它,因此当您需要将块保留更长时间时,复制块总是正确的。

现在,接受块参数的函数通常负责在必要时复制块。因此,在将块传递给这些函数时,您不需要做任何特别的事情。但是,在这种情况下,您将块传递给[NSArray arrayWithObject:],它采用普通对象参数。由于它不接受块参数,它不知道复制参数,所以它只会保留它。因此,当您将块传递给采用普通对象参数的方法时,您需要先复制它。

于 2012-10-24T18:45:14.170 回答
-1

如果您在这里阅读了非常好的文章,您会发现如何做到这一点。并特别注意那里提到的“首先将它们从堆栈中复制出来”的成语。

于 2012-10-24T07:33:56.313 回答