私はブロックで遊んでいて、奇妙な振る舞いに遭遇しました。これはインターフェース/実装であり、それを実行する機能を備えたブロックを保持するだけです。
@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(block)のスタックトレースです。デバッガー: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];
何が起きてる?