我一直在玩塊,遇到奇怪的行爲。 這是接口/實現,它只是擁有一個塊與執行它的能力:Objective-C帶閉包的塊引用宿主對象
@interface TestClass : NSObject {
#if NS_BLOCKS_AVAILABLE
void (^blk)(void);
#endif
}
- (id)initWithBlock:(void (^)(void))block;
- (void)exec;
@end
@implementation TestClass
#if NS_BLOCKS_AVAILABLE
- (id)initWithBlock:(void (^)(void))block {
if ((self = [super init])) {
blk = Block_copy(block);
}
return self;
}
- (void)exec {
if (blk) blk();
}
- (void)dealloc {
Block_release(blk);
[super dealloc];
}
#endif
@end
而普通實例並通過定期塊的工作:
TestClass *test = [[TestClass alloc] initWithBlock:^{
NSLog(@"TestClass");
}];
[test exec];
[test release];
使用參考塊到正被創建的對象並不:
TestClass *test1 = [[TestClass alloc] initWithBlock:^{
NSLog(@"TestClass %@", test1);
}];
[test1 exec];
[test1 release];
錯誤是EXC_BAD_ACCESS,上Block_copy(塊)堆棧跟蹤; 調試程序:0x000023b2 < 0050>添加爲0x18 $,%ESP
我不停地打轉轉,和移動初始化上述分配代碼,它的工作:
TestClass *test2 = [TestClass alloc];
test2 = [test2 initWithBlock:^{
NSLog(@"TestClass %@", test2);
}];
[test2 exec];
[test2 release];
並結合這兩個片段也工作:
TestClass *test1 = [[TestClass alloc] initWithBlock:^{
NSLog(@"TestClass %@", test1);
}];
[test1 exec];
[test1 release];
TestClass *test2 = [TestClass alloc];
test2 = [test2 initWithBlock:^{
NSLog(@"TestClass %@", test2);
}];
[test2 exec];
[test2 release];
這是怎麼回事?
實際上,'[TestClass alloc]'和'^ {...}'之間的評估順序是未定義的。在C級別,兩者都被評估爲'-initWithBlock:'的參數,因此在*'[TestClass alloc]被調用之前實際可以創建塊。 :) – 2011-05-18 23:20:07
@Jonathan確實!我已經編輯了相應的答案。 – 2011-05-18 23:23:05
謝謝,這是有道理的,這就是爲什麼我試圖分裂陳述。但是,如果將非工作代碼段和工作代碼段合併在一起,它是如何工作的? – elado 2011-05-18 23:26:33