Obj-c 在此队列中是 NSMutablearray 线程安全的,读取它也需要排队



我正在Xcode 7中开发我的IOS应用程序,我在全局NSMutableArray的线程安全性方面遇到了一些问题,该数组被多次读取以在表视图上进行一些更新。

由于一些奇怪的问题,我尝试将此队列添加到全局数组(全局到视图)的更新中,其中数组是从我调用的数据库函数更新的(编写为带有其他一些全局函数的类方法)。但是更新是从某些主线程调用的,但也从来自后台线程和计时器事件的其他调用调用。

我添加全局变量:

NSMutableArray *myMutArray ;
dispatch_queue_t the_Queue ;

然后在视图中出现

the_Queue = dispatch_queue_create("my_Queue", DISPATCH_QUEUE_SERIAL) ;

以及我用于更新数组的函数(来自另一个类实例)

-(void)update_array {
     dispatch_sync("my_Queue"),^{
         myMutArray = [[NSMutableArray alloc] initwithArray:[Globalfunction updatearrayfromdb] ] ;
     }
}

有了这个,我希望避免线程问题,但是是否有必要有一个读取功能,例如:

-(NSArray*)read_array{
   __block NSArray *array ;
   dispatch_sync("my_Queue",^{
         array = [NSArray arrayWithArray:myMutArray ] ;
    });
    return array;
}

或者,如果一直在主线程上执行此数组的读取,则不需要这样做吗?另外,dispatch_sync是在主线程上运行的块,还是我应该调用一个额外的函数来使它们在主线程上运行,因为所有方法都不需要在后台运行,但仍然可以从多个位置调用。我在想使用NSOperationQueue是否会更好:

-(void)update_array {
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        myMutArray = [[NSMutableArray alloc] initwithArray:[Globalfunction updatearrayfromdb] ] ;
 });
)

或者这会给出不同的结果吗?我的主要目标基本上是所有块都在主线程上运行,但按照调用它们的顺序。

我总是对此感到困惑的一件事是,这些块(我的调度方法和 NSOperation 方法)会在主线程上完成整个方法/块后被调用(f.ex 在 -(void) 与 20 行代码完全运行到完成后)还是它们会在方法/块中开始, 但是在刚刚执行了一行代码之后,还有更多的代码行在等待。(由于这是我们试图避免线程安全的事情,因此最好知道我的线程何时执行?

还有没有办法避免同一个块在添加多次时连续多次调用,例如当它像这样堆叠时:

call read
call update <- if this is the one progress now
call read
call read <- these returns the same so are unnecessary and would waste time
call read <- these returns the same so are unnecessary and would waste time
call read <- these returns the same so are unnecessary and would waste time

> NSMutableArray 不是线程安全的; 不适合同时写作,也不适合同时阅读

如果具有跨线程的可变数组,则需要序列化读取和写入。 最简单的方法是使用一个串行队列,您将所有操作dispatch_sync()到(如您提供的代码中)。

无需在主队列上执行所有操作(事实上,这样做可能会导致响应能力问题)。

或者,

如果写入相当不频繁,或者显示给用户(或其他)的数据可以稍微滞后,请考虑在NSMutableArray上调用copy以创建NSArray实例,因为这将是线程安全的。


主队列是串行的。 一次只能处理一个块,并且整个块必须执行并返回,然后才能执行另一个块。

最新更新