GCD / NSOperationQueue EXC_BAD_ACCESS

时间:2014-11-24 16:50:32

标签: ios asynchronous crash grand-central-dispatch nsoperationqueue

我使用GCD / NSOperationQueue进行异步删除。

我实现了以下代码:

- (void)deleteWithCompletionHandler:(Handler)completionHandler
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

[queue addOperationWithBlock:^{

    NSFileManager *fileManager = [NSFileManager defaultManager];

    NSError *error;

    if ([fileManager fileExistsAtPath:self.path]) {

        BOOL success = [fileManager removeItemAtPath:self.path error:&error];

    }

    NSOperationQueue *main = [NSOperationQueue mainQueue];

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{

        if (completionHandler) {

            completionHandler(error, nil);
        }
    }];
}];
}

以及以下内容:

- (void)deleteWithCompletionHandler:(Handler)completionHandler
{
dispatch_queue_t queue = dispatch_queue_create("My Queue", NULL);

dispatch_async(queue, ^{

    NSFileManager *fileManager = [NSFileManager defaultManager];

    NSError *error;

    if ([fileManager fileExistsAtPath:self.path]) {

        BOOL success = [fileManager removeItemAtPath:self.path error:&error];

    }


    dispatch_async(dispatch_get_main_queue(), ^{

        if (completionHandler) {

            completionHandler(error, nil);
        }
    });
});
}

两个代码段都会在返回主线程时导致EXC_BAD_ACCESS。

我做错了什么?项目中的某些代码不使用ARC。

感谢。

1 个答案:

答案 0 :(得分:1)

由于您没有使用ARC,因此堆栈变量未初始化为0 / nil。因此completionHandler(error, nil);将使用随机堆栈垃圾调用error

这是在查看代码时突出的一个问题,而clang静态分析器应该很容易理解。我建议您在代码上运行分析器并查看所有警告。

潜在的其他问题也是如此,如果您需要更多帮助,请提供您的崩溃报告。

此外,您的队列变量超出范围,因此您要么泄漏它(在MRR情况下),要么在使用时释放它(在ARC情况下)。您应该只使用全局并发队列。