gdb remote返回错误:E08调用完成块时(EXC_BAD_ACCESS)

spl*_*ter 8 objective-c objective-c-blocks automatic-ref-counting ios6

我正在使用ARC而且在iOS6上我遇到了一个奇怪的崩溃:gdb remote返回了一个错误: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);
}];
Run Code Online (Sandbox Code Playgroud)

调用代码:

[[Controller sharedController] method1:^(NSMutableArray *a) {
    //save result in model (singleton)
    [Model sharedModel].a = a;
    [weakSelf refreshUI];

} withFailedBlock:^(NSInteger errorCode,NSString *error) {
    ;//show alert

}];
Run Code Online (Sandbox Code Playgroud)

当我检查它周围的块和值时,它们似乎没问题.我也有NSZombie.我的completionBlock应该被自动复制,因为它是从块中引用的.

我在这里错过了什么?我也看过iOS5和4.3上的崩溃,但从来没有gdb远程返回错误:E08.调试器中的信息在这些情况下也没有帮助.我正在使用PLWeakCompatibility,以便我可以在iOS4.3下支持__weak

Tie*_*eme 0

您还有这个问题吗?

为什么在这种情况下需要weakSelf。在这种情况下,你看起来不像是在捕捉自我。当你忽略它时,代码是否仍然崩溃?

顺便说一句,我认为当你试图简化你的问题时,你的 method1 实现有点混乱。

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

看起来不像是有效的方法实现。不应该是这样的吗:

- (void) method1: (void(^)(NSMutableArray *a)) completionBlock withFailedBlock:(void(^)(NSInteger errorCode,NSString *error)) failedBlock {
    ...
}
Run Code Online (Sandbox Code Playgroud)