此代码可以保持线程salfe?(IOS)

此代码可以保持线程salfe?(IOS),ios,multithreading,Ios,Multithreading,下面是课堂: @interface PhotoManager () @property (nonatomic,strong,readonly) NSMutableArray *photosArray; @property (nonatomic, strong) dispatch_queue_t concurrentPhotoQueue; @end 我想使属性Photosaray(setter和getter)线程安全: - (void)addPhoto:(Photo *)phot

下面是课堂:

@interface PhotoManager ()
    @property (nonatomic,strong,readonly) NSMutableArray *photosArray;
    @property (nonatomic, strong) dispatch_queue_t concurrentPhotoQueue;
@end
我想使属性Photosaray(setter和getter)线程安全:

- (void)addPhoto:(Photo *)photo
{
    if (photo) {
        dispatch_barrier_async(self.concurrentPhotoQueue, ^{ 
            [_photosArray addObject:photo];
            dispatch_async(dispatch_get_main_queue(), ^{
                //Notification to update the UI; 
            });
        });
    }
}
和getter方法:

 - (NSArray *)photos
    {
        __block NSArray *array;
        dispatch_sync(self.concurrentPhotoQueue, ^{
            array = [NSArray arrayWithArray:_photosArray];
        });
        return array;
    }
但是apple develop文档说:“作为一种优化,这个函数在可能的情况下调用当前线程上的块。” 因此,如果concurrentPhotoQueue队列不是“当前队列”,则concurrentPhotoQueue中的屏障可能不会阻止其他线程,例如getter可能会调用主线程。换句话说,如果一个线程设置了可变数组,而另一个线程同时读取可变数组,那么getter方法仍然不是线程安全的

我的意见对吗?如果是,如何修改getter方法?
注意:我从博客中引用了这些代码。

当优化没有破坏默认行为时,它们通常会跳入


当没有其他线程添加照片时,getter可能在主线程上执行。现在,如果一个线程在主线程上运行
photos
getter时突然进入
addPhotos
方法,作为一种优化选择,barrier调用可能会在内部知道它应该引用的队列现在是主队列,而不是
concurrentPhotoQueue
。听起来很合理。

我进行了测试,结果是它们都在concurrentPhotoQueue提供的不同线程上运行,包括dispatch\u barrier\u sync()方法。感谢当(int i=0;i<1000;i++){dispatch\u async(dispatch\u get\u global\u queue)的线程限制达到(64)
时容易出现死锁(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^(){[photomanager addPhoto:photo];[photomanager photos];}
你能告诉我为什么吗?如果你杀死应用程序,它会生成崩溃报告,并显示消息
DISPATCH Thread Soft Limit:64(同步操作中阻塞了太多的调度线程)
。gcd似乎为并发队列上的每个调度同步创建了一个线程。很抱歉,我没有更好的解释为什么会发生这种情况以及如何避免它。我认为是
for
循环导致了问题,因为每个循环都会异步向concurrentPhotoQueue提交任务,但此方法
调度\u是一个障碍_async
使concurrentPhotoQueue上每次只执行一个任务,因此有许多线程(通过dispatch\u get\u global\u queue或concurrentPhotoQueue进行调度)被concurrentPhotoQueue中的
dispatch\u barrier\u async
阻止。