objective-c - 对可能被objective-c中的另一个线程锁定的对象执行 "dirty read"的最佳方法

标签 objective-c multithreading synchronization dirtyread

我想知道以下是否是读取和复制可能被另一个线程锁定的对象的最佳方法?

-(NSObject*) getCopyOfActiveObjectsOfType:(Class) objectClass
{
    NSMutableArray* copy = [NSMutableArray arrayWithArray:[self.activeObjects objectForKey:objectClass]];

    return copy;
}

我有如下几种方法可以锁定相关对象以向数组添加或删除对象。
-(void) addObject:(NSObject *)object toPoolOfObjects:(NSMutableDictionary*) objects
{
    Class objectClass = [object class];
    @synchronized (objects)
    {
        NSMutableArray* objectArray = [objects objectForKey:objectClass];

        if(objectArray == nil)
        {
            objectArray = [[[NSMutableArray alloc] init] autorelease];
            [objects setObject:objectArray forKey:objectClass];
        }
        [objectArray addObject:object];
    }

}

最佳答案

使用 @synchronize替代语言的方法或等效方法:

  • 如果您的实例是从多个线程访问的并且它不是不可变的,则您将需要围绕所有访问可以变异的状态的方法的同步块(synchronized block)
  • 如果没有访问器/方法更改对象的内部状态,则您的对象是不可变的。

  • 您正在使用标准 NSMutableArray/NSMutableDictionary 原语来表示状态,但是这些原语不是线程安全的,因此在跨线程共享时需要锁。在不了解 API 及其消费者的访问与更新频率的情况下,很难推荐特定的解决方案。

    如果您的 API 主要用于读取,您可以使用以下解决方案,该解决方案实现写入时复制。尽管与往常一样,您必须进行概要分析以确定解决方案是否满足您的性能要求。
    - (NSArray *)getActiveObjectsOfType:(Class)objectClass {
        @synchronize(self.activeObjects) {
            return [self.activeObjects objectForKey:objectClass];
        }
    }
    
    - (void)addObject:(NSObject *)object {
        Class objectClass = [object class];
    
        // synchronize access to activeObjects
        @synchronize(self.activeObjects) {
            NSArray *existingArray = [[[self.activeObjects objectForKey:objectClass] retain] autorelease];
    
            NSMutableArray *newArray;
            if (existingArray) {
                newArray = [NSMutableArray arrayWithArray:existingArray];
            } else {
                newArray = [NSMutableArray array];
            }
    
            [newArray addObject:object];
    
            [self.activeObjects setObject:newArray forKey:objectClass];
        }
    }
    

    此解决方案需要注意的重要一点是 getActiveObjectsOfType 返回的 NSArray 是不可变的。

    关于objective-c - 对可能被objective-c中的另一个线程锁定的对象执行 "dirty read"的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7309414/

    相关文章:

    ios - 使用 NSRecursiveLock 从方法返回值

    java - 同步取决于字符串初始化

    ios - 在继承的类中覆盖 NSLayoutConstraint

    iphone - 无法以编程方式设置 UIButton 操作

    ios - 在 iOS7 中禁用 UINavigationController 的旋转

    python - ZeroVM导入错误: No module named thread

    c++ - 同时读取和写入 vector 导致异常

    iphone - 如何使用日期对表格单元格上的行内容进行排序

    multithreading - F# 并行设计模式

    c - 使两个程序通过网络同步工作