如何在Objective-C中创建自定义类线程安全

时间:2016-10-12 07:43:30

标签: ios objective-c multithreading thread-safety

我有TableViewController使用索引N处的项目作为第N行的表格视图单元格。由于可以从不同的线程访问数组索引N,因此我创建了一个ThreadSafeMutableArray类它在dispatch_sync内进行读取并在dispatch_barrier_async下写入。

假设我在索引N处获取对象,比如使用Song *currSong = self.entries[N];,然后更改此对象的属性。我是否正确理解我需要以线程安全的方式进行这些更改(因为例如,tableview可能会询问单元格N处的对象,同时可能会更新单元格N中的对象,因为图像对象为它是从网络收到的)?如果是,那么使我的自定义类线程安全的最简单方法是什么?

例如:在ThreadSafeMutableArray案例中,我通过覆盖以下方法并在新版本中使用dispatch_syncdispatch_barrier_async来实现这一目标方法的实施。

-(NSUInteger) count
-(id) objectAtIndex:(NSUInteger)index;
-(void) insertObject:(id)anObject atIndex:(NSUInteger)index;
-(void) removeObjectAtIndex:(NSUInteger)index;
-(void) addObject:(id)anObject;
-(void) removeLastObject;
-(void) replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;

2 个答案:

答案 0 :(得分:1)

您需要确定“线程安全”在自定义类/应用程序的上下文中的含义。您可能只想要数据完整性,这意味着没有线程看到无效或部分存储的值,例如想想原子读/写操作;或者您可能需要模型完整性,例如多个项目的相互关系总是正确的 - 就像在你的可变数组中一样;或者这些之间的东西,例如想到计数器递增 - 它不像保持表示可变结构的对象的图形一致,但比简单的原子读取或写入更复杂。等等,线程安全是一个很大的话题!

一旦您知道自定义对象需要什么,就可以从原子属性中选择简单的读/写完整性,锁定更复杂的组合,GCD同步组合,异步,屏障,顺序和并发队列等。

简而言之,没有一个简单的答案。研究各种选择,考虑您的要求,并挑选。您已经在使用GCD来实现线程安全,这很好!如果您想出一个设计并遇到问题,您可以随时询问。

您可能会发现this article对原子属性的好处或其他方面感兴趣。作者可能对原子有点苛刻,但是它确实值得一读。

HTH

答案 1 :(得分:0)

实现此目标的最简单方法是在TableViewController中创建一个单一的访问方法,并使用@syncrhonized指令来保护访问权限。

    - (void)updateObjectAt:(NSUInteger)index {
        @synchronized(itemArray) {
            // Everything between the braces is protected by the @synchronized directive.
            itemArray[index].update();
        }
    }

@synchornized指令锁定数组,代码块中的任何内容都可以安全地访问和更改数组中的项目。如果任何其他方法需要访问数组,只需将其包装在数组的@syncrhonized锁中。