Лучший способ сделать «грязное чтение» объекта, который может быть заблокирован другим потоком в target-c - PullRequest
2 голосов
/ 05 сентября 2011

Мне было интересно, является ли следующий способ лучшим способом прочитать и сделать копию объекта, который может быть заблокирован другим потоком?

-(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];
    }

}

1 Ответ

0 голосов
/ 15 ноября 2011

Использование метода @synchronize или его эквивалента на альтернативных языках:

  • , если к вашему экземпляру обращаются из нескольких потоков и он не является неизменным , вам потребуются блоки синхронизации вокругвсе методы, обращающиеся к состоянию, которое может быть изменено
    • ваш объект неизменен , если ни один из методов доступа / методов не изменяет внутреннее состояние объекта.

Вы используете стандартные примитивы 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];
    }
}

Важно отметить, что для этого решения NSArray, возвращаемый getActiveObjectsOfType, является неизменным.

...