【发布时间】:2015-03-01 10:20:05
【问题描述】:
我目前正在实现一个多线程应用程序,但遇到了一个奇怪的竞争条件(导致 ARC 问题:对象 0x7f8bcbd6a1c0 错误:未分配指针被释放)。
该应用程序创建多个 NSOperations,每个 NSOperations 都在下载和处理信息。就像在这些 NSOperations 中的每一个中一样,可能会发生错误(例如,Web 服务不可用),我想向上传播错误以便我可以处理它。但是,我似乎遇到了竞争条件,操作尝试访问无效内存。
显示内存访问问题的简单示例如下:
- (void) createError: (NSError**) err {
*err = [[NSError alloc] initWithDomain:@"Test" code:12345 userInfo:nil];
}
- (void)viewDidLoad {
[super viewDidLoad];
__block NSError *globalError = nil;
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSOperation *op = nil;
for (int i=0; i<10; i++) {
op = [NSBlockOperation blockOperationWithBlock:^{
NSError *err = nil;
[self createError:&err];
// This loop increases the chance to get the race condition
for (int j=0; j<10000;j++) {
@synchronized(globalError) {
globalError = err;
}
}
}];
[queue addOperation:op];
}
[queue waitUntilAllOperationsAreFinished];
if (globalError) {
NSLog(@"An error occured in at least one of the operations");
}
}
每当我运行这个程序时,我都会遇到异常。主要是对象 0x7fc0b860e860 的错误:未分配指针被释放,但是,有时我在调试器中也遇到了 EXC_BAD_ACCESS (code=EXC_I386_GPFLT) 中断。
我添加了超过 10000 次迭代的 for 循环,只是为了增加竞争条件发生的机会。如果我离开它,错误只会在极少数情况下发生(但仍然必须修复,显然我在这里做错了)。
【问题讨论】:
-
我想我找到了。我在 nil 上同步,它实际上不执行任何同步。
标签: objective-c multithreading concurrency automatic-ref-counting nsoperationqueue