我使用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。
谢谢。
发布于 2014-11-24 12:17:57
由于您没有使用ARC,所以您的堆栈变量不会初始化为0/nil。因此,completionHandler(error, nil);
将与error
的随机堆栈垃圾一起调用。
在查看代码时,这是一个突出的问题,clang静态分析器应该很容易捕捉到这个问题。我建议您在代码上运行分析器,并查看所有警告。
可能还有其他的问题潜伏着,所以如果你需要更多的帮助,请提供你的坠机报告。
另外,队列变量超出了作用域,所以要么泄漏它(在MRR情况下),要么在仍然使用时释放它(在ARC情况下)。您可能应该只使用一个全局并发队列。
https://stackoverflow.com/questions/27109893
复制