私は ARC を使用していますが、iOS6 では奇妙なクラッシュが発生することがあります: gdb リモートがエラーを返しました: E08
スタックトレースでは、前のメソッドは完了ブロックを呼び出す行にあります。ブロックと ARC についてよく読んでいますが、次のコンテキストでそれらを使用する場合はまだ自信がありません。
(メソッドを簡略化し、一部のコードを省略)
- (void) method1: (void(^)(NSMutableArray *a)) completionBlock withFailedBlock:(void(^)(NSInteger errorCode,NSString *error)) failedBlock {
__weak Controller *weakSelf = self;
...
if(condition)
completionBlock(weakSelf.a);
//still do method2, since we might get updated data
[weakself.service method2:^(NSMutableArray *a2) {
weakSelf.shouldRefresh = NO;
...
completionBlock(a2); //<-- sometimes crashes here
} withFailedBlock:^(NSInteger errorCode, NSString *error) {
failedBlock(errorCode, error);
}];
} withFailedBlock:^(NSInteger errorCode, NSString *error) {
failedBlock(errorCode, error);
}];
呼び出しコード:
[[Controller sharedController] method1:^(NSMutableArray *a) {
//save result in model (singleton)
[Model sharedModel].a = a;
[weakSelf refreshUI];
} withFailedBlock:^(NSInteger errorCode,NSString *error) {
;//show alert
}];
ブロックとその周囲の値を調べると、問題ないように見えます。NSZombieもオンにしています。ブロック内から参照されるため、私の completionBlock は自動的にコピーされるはずです。
ここで何が欠けていますか?iOS5 と 4.3 でもクラッシュが見られましたが、gdb リモートがエラー E08 を返したことはありません。これらの場合、デバッガーからの情報も役に立ちませんでした。iOS4.3 で __weak をサポートできるようにPLWeakCompatibilityを使用しています。