8

我正在使用 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);
}];

调用代码:

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

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

}];

当我检查块及其周围的值时,它们似乎还可以。我也有 NSZombie。我的完成块应该被自动复制,因为它是从块内引用的。

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

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 回答