Objective c iOS并发:NSOperationQueue和ARC问题

Objective c iOS并发:NSOperationQueue和ARC问题,objective-c,multithreading,concurrency,automatic-ref-counting,nsoperationqueue,Objective C,Multithreading,Concurrency,Automatic Ref Counting,Nsoperationqueue,我目前正在实现一个多线程应用程序,遇到一个奇怪的争用条件(导致ARC问题:对象0x7f8bcbd6a1c0的错误:未分配要释放的指针) 该应用程序创建多个操作,每个操作都在下载和处理信息。由于在这些操作中的每一个操作中都可能发生错误(例如,web服务不可用),因此我希望传播错误,以便能够处理它。然而,我似乎遇到了竞争条件,操作试图访问无效内存 下面是一个显示内存访问问题的简单示例: - (void) createError: (NSError**) err { *err = [[NSEr

我目前正在实现一个多线程应用程序,遇到一个奇怪的争用条件(导致ARC问题:对象0x7f8bcbd6a1c0的错误:未分配要释放的指针)

该应用程序创建多个操作,每个操作都在下载和处理信息。由于在这些操作中的每一个操作中都可能发生错误(例如,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");
    }
}
-(void)createError:(NSError**)err{
*err=[[NSError alloc]initWithDomain:@“测试”代码:12345用户信息:nil];
}
-(无效)viewDidLoad{
[超级视图下载];
__块N错误*全局错误=零;
NSOperationQueue*队列=[[NSOperationQueue alloc]init];
NSOP操作*op=nil;

对于(int i=0;i指令
@synchronized
使用您传递的对象来控制同步,因此,正如您所注意到的,您正在尝试在
nil
上同步。即使它不是
nil
,指令
@synchronized
引用的对象每次都是不同的对象,这在很大程度上挫败了尝试同步


最简单的更改是使用
@synchronized(self)
。或者,创建一个
NSLock
对象,然后在访问
globalError
lock
unlock
将其解锁。或者,如果这是一个高需求情况,则使用GCD队列(串行队列或读写器模式).

我想我找到了。我在nil上进行了同步,这实际上不执行任何同步。