8

私は 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を使用しています。

4

1 に答える 1

0

あなたはまだこの問題を抱えていますか?

この場合、なぜweakSelfが必要なのですか。この状況では、自己をキャプチャしているようには見えません。省略してもコードはクラッシュしますか?

ところで、質問のために単純化しようとしたときに、method1の実装が少し面倒になったと思います。

- (void) method1: (void(^)(NSMutableArray *a)) completionBlock withFailedBlock:(void(^)(NSInteger errorCode,NSString *error)) failedBlock {
    ...
} withFailedBlock:^(NSInteger errorCode, NSString *error) {
    ...
}];

有効なメソッド実装のようには見えません。次のようなものではないでしょうか。

- (void) method1: (void(^)(NSMutableArray *a)) completionBlock withFailedBlock:(void(^)(NSInteger errorCode,NSString *error)) failedBlock {
    ...
}
于 2013-02-04T18:10:36.687 に答える