这对我来说似乎是一种非常奇怪的互动,但同时它不仅起作用,而且在此过程中不会引发任何警告或错误。只是希望更好地理解一般的块,以及为什么这样的事情是对还是错。
有什么理由不应该这样做吗?
NSArray *array = [NSArray arrayWithObjects:^{NSLog(@"Block 1");}, ^{NSLog(@"Block 2");}, ^{NSLog(@"Block 3");}, nil];
for (id block in array) {
[block invoke];
}
答案 0 :(得分:4)
将块放入NSArray
s很好;他们是对象。事实上,他们继承自NSObject
。
但是,您确实需要复制它们。这些块是在堆栈上创建的,需要移动到堆中才能超过当前方法的结尾。如果您正在使用ARC,这很容易:
NSArray *array = [NSArray arrayWithObjects:[^{NSLog(@"Block 1");} copy], ...
在MRR下,您需要平衡copy
,因此您有两个不愉快的选项:使用temps,或在创建数组后立即枚举数组并将release
发送给其所有成员。
另一方面,发送invoke
并非完全犹太教,因为这是私有方法。调用块的唯一完全API兼容的方法是使用函数调用语法:
typedef GenericBlock dispatch_block_t;
for( GenericBlock block in array ){
block();
}
答案 1 :(得分:1)
当然,那没关系。为什么不好?
在像JavaScript这样的语言中,这种技术在注册事件处理程序时很常见。
object.clickHandlers.push(function() { doStuff() });
object.clickHandlers.push(function() { doMoreStuff() });
我认为类似的技术不能与ObjC块一起使用,因为它们是真实的对象。
对我来说,更有趣的问题是,无论你的目标是什么,这种模式是最好的选择。你没有真正告诉过我们。
答案 2 :(得分:1)
Objective-C中的块是“一等公民”对象。无论你对常规对象做什么,无论是作为参数传递,存储在数组还是字典中,依此类推,你都可以阻止对象。
例如,块对象数组可用于编码在编译时未知的一系列动作;字符串键控的块对象字典可用于实现脚本语言,等等。
调用从集合中检索的块的最佳方法是将其转换为正确的类型,并使用常规块调用语法。