我只是想,因为如果我创建其中两个然后将它们添加到NSArray中,你可以将块视为对象吗?有没有办法从数组中执行它们?
int (^Block_001)(void) = ^{ return 101; };
int (^Block_002)(void) = ^{ return 202; };
NSArray *array = [NSArray arrayWithObjects:Block_001, Block_002, nil];
编辑:为了清晰而更新Per @ davedelong的优秀答案
int (^Block_001)(void) = [^{ return 101; } copy];
int (^Block_002)(void) = [^{ return 202; } copy];
NSArray *array = [NSArray arrayWithObjects:Block_001, Block_002, nil];
[Block_001 release];
[Block_002 release];
答案 0 :(得分:60)
@KennyTM和@David是正确的,但您的代码可能有误。原因如下:
使用对象创建NSArray
时,会retain
放入对象。在块的情况下,它使用Block_retain
函数。这意味着数组保留了您创建的块,但是生成在堆栈上的 (块是可以在堆栈上创建的Objective-C对象的非常罕见的示例之一,而无需深入研究荒谬的技巧)。这意味着只要此方法退出,您的数组现在就指向垃圾,因为它指向的块不再存在。要做到这一点,你应该这样做:
int (^Block_001)(void) = [^{ return 101; } copy];
int (^Block_002)(void) = [^{ return 202; } copy];
NSArray *array = [NSArray arrayWithObjects:Block_001, Block_002, nil];
[Block_001 release];
[Block_002 release];
通过在块上调用copy
,您可以显式地将块移出堆栈并移到堆上,在方法/函数退出后它可以安全地保留。然后,在将块添加到阵列后,您必须平衡copy
(因为NARC规则)与后续调用release
。有意义吗?
答案 1 :(得分:29)
当然,您只需使用()
调用它就像任何其他块一样,但您需要对从NSArray
检索的值进行类型转换。这是一个例子(添加了typedef,因为否则我的头疼了):
typedef int (^IntBlock)(void);
IntBlock Block_001 = ^{ return 101; };
IntBlock Block_002 = ^{ return 202; };
NSArray *array = [NSArray arrayWithObjects:Block_001, Block_002, nil];
int x = ((IntBlock)[array objectAtIndex:0]) (); // now x == 101
答案 2 :(得分:7)
当然可以。
int (^x)(void) = [array objectAtIndex:0];
printf("%d\n", x()); // prints 101.