コードにErrorBlock(errorBlock)が定義されており、複数回呼び出すことができます。呼び出しについて一度だけ通知されたいので、私のアイデアは、ErrorBlock(errorBlock)を別の(pErrorBlock)でラップし、その1つをnilに設定することでした。
ここで、innerBlockの参照をnilに設定するクリーンアップメソッドが必要でした。しかし、内側のブロックをクリーンアップメソッドに渡すと(テスト1)、内側のErrorBlockをnil selfに設定したとき(テスト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
私の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();
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