Избегайте получения освобожденных объектов от одновременно используемых методов доступа - PullRequest
2 голосов
/ 31 января 2012

В моем многопоточном приложении есть свойство, к которому могут обращаться несколько потоков.Свойство определяется как @property (retain) NSObject *status.

Как атомарно получить и сохранить собственность, чтобы я мог безопасно использовать ее в своей локальной области?Какова наилучшая практика для хранения и извлечения такого значения?

NSObject *status = [self status];
[... do some processing on status ...]

// But: I cannot rely on the object assigned to my status variable 
// still being valid, since another thread might have used my 
// [self setStatus] accessor, implicitly calling a release on the old object, 
// releasing it under my feet.
// Not even NSObject *status = [[self status] retain]; would fix that.

1 Ответ

4 голосов
/ 31 января 2012

В моем многопоточном приложении есть свойство, к которому могут обращаться несколько потоков. Свойство определяется как @property (retain) NSObject * status.

атомное значение по умолчанию - ключевое слово или спецификатор не требуются.

Как я могу получить и сохранить собственность атомным способом, чтобы я мог безопасно использовать ее в своем местном масштабе?

Поскольку это atomic, retain ed, readwrite и @synthesized, вы всегда можете использовать средства доступа. При условии, что вы обращаетесь к ivar напрямую через инициализаторы и только dealloc и используете средства доступа везде, это будет безопасно в отношении того, о чем вы спрашиваете. Возвращаемое значение retain + autoreleased. Поскольку он автоматически освобожден, объект будет жить - по крайней мере до тех пор, пока не будет извлечен верхний пул автоматического выпуска в локальном потоке.

В последний раз, когда я проходил, это выглядело примерно так (в простой форме):

- (NSObject *)object
{
    enter_object_level_spin_lock();
    id ret = [[object retain] autorelease];
    exit_object_level_spin_lock();
    return ret;
}

хотя я не помню, был ли autorelease в замке или нет (в идеале он был бы снаружи для более короткого времени блокировки).

Как лучше хранить и получать такое значение?

Атомарные свойства очень мало влияют на параллелизм или безопасность потоков - не считайте их заменой правильной безопасности потоков. Также необычно, что безопасность потоков покрывается тем, что предоставляют средства доступа к атомарным свойствам. Как правило, для правильной параллельной программы вам понадобится больше, чем просто атом. Я очень очень редко использую атомарные свойства и делаю несколько сумасшедших параллельных программ. Если вам нужен высокопроизводительный параллелизм транзакций, вам нужно знать, как эффективно использовать блокировки. Конечно, есть много способов избежать параллельных проектов. Мое автоматическое решение включает в себя обработку блокировки самостоятельно.

...