我使用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。
感谢。
答案 0 :(得分:1)
由于您没有使用ARC,因此堆栈变量未初始化为0 / nil。因此completionHandler(error, nil);
将使用随机堆栈垃圾调用error
。
这是在查看代码时突出的一个问题,而clang静态分析器应该很容易理解。我建议您在代码上运行分析器并查看所有警告。
潜在的其他问题也是如此,如果您需要更多帮助,请提供您的崩溃报告。
此外,您的队列变量超出范围,因此您要么泄漏它(在MRR情况下),要么在使用时释放它(在ARC情况下)。您应该只使用全局并发队列。