iphone - 线程安全 : NSOperationQueue + [array addObject]

标签 iphone ios concurrency nsoperationqueue

我找不到任何示例如何在使用操作队列时处理相同(类)变量。在 C 和线程中,它是关于互斥锁的。那么,当NSOperationQueue启动一个线程进行操作,类变量被修改时会发生什么呢?它是线程安全的吗?谢谢。

@interface MyTest {
    NSMutableArray *_array;
}
@end

-(id)init
{
    ...
    _array = [NSMutableArray new]; // class variable

        // queue time consuming loading
    NSOperationQueue *queue = [NSOperationQueue new];
    NSInvocationOperation *operation =
        [NSInvocationOperation initWithTarget:self
                                     selector:@selector(populate)
                                       object:nil];
    [queue addOperation:operation];

        // start continuous processing
    [NSTimer scheduledTimerWithTimeInterval:0.1
                                     target:self
                                   selector:@selector(processing)
                                   userInfo:nil
                                    repeats:YES];
    ...
}

-(void)populate
{
    while (...)
    {
        id element = ...; // time consuming

            // modify class variable "_array" from operation's thread (?)
        [_array addObject:element];

            // Ok, I can do instead of addObject
            // performSelectorOnMainThread:withObject:waitUntilDone:
            // but is it the only way? Is it needed?
    }
}

    // access and/or modify class variable "_array"
-(void)processing
{
    NSLog(@"array.count = %d", array.count);
    for (id i in _array)
    {
        [_array addObject:[NSNumber numberWithInt:rand() % 100]];
            // etc...
    }
}

最佳答案

不,这不是线程安全的,如果你启动一个线程对一个可以被其他线程修改的类变量做一些工作,那么它不是线程安全的,如果在 populate 运行时从某个线程调用处理另一个然后当 foreach 循环看到数组已被修改时你可能会得到一个异常,尽管你在你的例子中修改 foreach 循环内的数组时无论如何你都会得到那个异常(你不应该这样做,并且程序将抛出一个异常)...解决这个问题的一种方法是在数组上使用同步块(synchronized block),它将确保同步块(synchronized block)不会同时执行,线程阻塞直到一个同步块(synchronized block)完成,例如

    -(void)populate
    {


        while (...)
        {
            id element = ...; // time consuming

                // modify class variable "_array" from operation's thread (?)
      @synchronized(_array)
        {
            [_array addObject:element];

        }          // Ok, I can do instead of addObject
                // performSelectorOnMainThread:withObject:waitUntilDone:
                // but is it the only way? Is it needed?
        }

    }

        // access and/or modify class variable "_array"
    -(void)processing
    {


          @synchronized(_array)
         {
            NSLog(@"array.count = %d", array.count);
            for (id i in _array)
            {
                //you shouldnt modify the _array here you will get an exception
                    // etc...
            }
        }
    }

关于iphone - 线程安全 : NSOperationQueue + [array addObject],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8597832/

相关文章:

ios - 重新安排通知操作通知不起作用 Swift

java - java中使用多线程下载

.net - 等同于Akka,但适用于.NET(并发框架)

iphone - 核心数据: Editing many attributes laggy performance

iphone - 如何在 Windows 7 上安装配置文件进行测试

iphone - 如何使 Three20 的 TTStyledTextLabel 与外部图像配合使用?

java - 复合编辑的并发性

iphone - 用于演示应用程序的最佳 iPhone/iOS 框架

ios - 使用 xib 和 tableView 的多个 View

ios - 如何避免雷达图中 X 轴值和 Y 轴值重叠?