【发布时间】:2013-01-24 10:41:34
【问题描述】:
我的代码中定义了一个可以多次调用的 ErrorBlock (errorBlock)。 虽然我只想被告知一次有关呼叫的信息,但我的想法是将我的 ErrorBlock (errorBlock) 包装在另一个 (pErrorBlock) 中并将其设置为 nil。
现在我想要一个清理方法,将 innerBlock 的引用设置为 nil。但是当我将内部块交给清理方法(测试 1)时,当我将内部 ErrorBlock 设置为 nil 自身(测试 2)时,我得到了不同的结果。
如何使用测试 1 的代码(稍作修改)获得测试 2 的结果?
我的第一个测试,鞋子一个我看不懂的结果:
-(void)testBlocks{
__block ErrorBlock pErrorBlock= ^(void){
NSLog(@"Foo");
};
NSLog(@"test: %p",pErrorBlock);
ErrorBlock errorBlock = ^(void){
dispatch_async(dispatch_get_main_queue(), ^{
if(pErrorBlock){
NSLog(@"call: %p",pErrorBlock);
pErrorBlock();
}
[self cleanupErrorBlockWith:pErrorBlock];
});
};
errorBlock();
errorBlock();
}
- (void) cleanupErrorBlockWith:(ErrorBlock)errorBlock{
NSLog(@"cleanup: %p",errorBlock);
errorBlock = nil;
NSLog(@"after cleanup: %p",errorBlock);
}
结果:
2013-02-08 16:39:04.484 Tests[9501:907] test: 0x3a6ba8
2013-02-08 16:39:04.496 Tests[9501:907] call: 0x3a6ba8
2013-02-08 16:39:04.497 Tests[9501:907] Foo
2013-02-08 16:39:04.498 Tests[9501:907] cleanup: 0x3a6ba8
2013-02-08 16:39:04.499 Tests[9501:907] after cleanup: 0x0
2013-02-08 16:39:04.500 Tests[9501:907] call: 0x3a6ba8
2013-02-08 16:39:04.501 Tests[9501:907] Foo
2013-02-08 16:39:04.502 Tests[9501:907] cleanup: 0x3a6ba8
2013-02-08 16:39:04.503 Tests[9501:907] after cleanup: 0x0
我的第二个测试,期望的结果是:
-(void)testBlocks{
__block ErrorBlock pErrorBlock= ^(void){
NSLog(@"Foo");
};
NSLog(@"test: %p",pErrorBlock);
ErrorBlock errorBlock = ^(void){
dispatch_async(dispatch_get_main_queue(), ^{
if(pErrorBlock){
NSLog(@"call: %p",pErrorBlock);
pErrorBlock();
NSLog(@"cleanup: %p",pErrorBlock);
pErrorBlock = nil;
NSLog(@"after cleanup: %p",pErrorBlock);
}
});
};
errorBlock();
errorBlock();
}
结果:
2013-02-08 16:42:18.485 Tests[9540:907] test: 0x3a6ba8
2013-02-08 16:42:18.496 Tests[9540:907] call: 0x3a6ba8
2013-02-08 16:42:18.498 Tests[9540:907] Foo
2013-02-08 16:42:18.499 Tests[9540:907] cleanup: 0x3a6ba8
2013-02-08 16:42:18.500 Tests[9540:907] after cleanup: 0x0
【问题讨论】:
-
errorBlock = nil;肯定没有任何效果,因为它是作为参数传递的......
标签: ios objective-c methods pass-by-reference block