При каких обстоятельствах атомарные свойства полезны?

Свойства Objective-C по умолчанию равны атомарным , который гарантирует, что аксессоры являются атомарными, но не обеспечивает общую безопасность потоков (согласно этот вопрос ). Мой вопрос: не являются ли атомарные свойства избыточными в большинстве сценариев параллелизма? Например:

Сценарий 1: изменяемые свойства

@interface ScaryMutableObject : NSObject {}

@property (atomic, readwrite) NSMutableArray *stuff;

@end

void doStuffWith(ScaryMutableObject *obj) {
    [_someLock lock];
    [obj.stuff addObject:something]; //the atomic getter is completely redundant and could hurt performance
    [_someLock unlock];
}

//or, alternatively
void doStuffWith(ScaryMutableObject *obj) {
    NSMutableArray *cachedStuff = obj.stuff; //the atomic getter isn't redundant
    [_someLock lock];
    [cachedStuff addObject:something]; //but is this any more performant than using a nonatomic accessor within the lock?
    [_someLock unlock];   
}

Сценарий 2: неизменяемые свойства

Я думал, что, возможно, атомарные свойства будут полезны для избежания блокировок при работе с неизменяемыми объектами, но поскольку неизменяемые объекты могут указывать на изменяемые объекты в Objective-C это не особо помогает:

@interface SlightlySaferObject : NSObject {}

@property (atomic, readwrite) NSArray *stuff;

@end

void doStuffWith(SlightlySaferObject *obj) {
    [[obj.stuff objectAtIndex:0] mutateLikeCrazy];//not at all thread-safe without a lock
}

Единственные сценарии, которые я могу придумать, когда безопасно использовать атомарные аксессоры без блокировки (и, следовательно, вообще стоит использовать атомарные свойства):

  1. Работа с свойства, которые Мой вопрос: не являются ли атомарные свойства избыточными в большинстве сценариев параллелизма? Например:

    Сценарий 1: изменяемые свойства

    @interface ScaryMutableObject : NSObject {}
    
    @property (atomic, readwrite) NSMutableArray *stuff;
    
    @end
    
    void doStuffWith(ScaryMutableObject *obj) {
        [_someLock lock];
        [obj.stuff addObject:something]; //the atomic getter is completely redundant and could hurt performance
        [_someLock unlock];
    }
    
    //or, alternatively
    void doStuffWith(ScaryMutableObject *obj) {
        NSMutableArray *cachedStuff = obj.stuff; //the atomic getter isn't redundant
        [_someLock lock];
        [cachedStuff addObject:something]; //but is this any more performant than using a nonatomic accessor within the lock?
        [_someLock unlock];   
    }
    

    Сценарий 2: неизменяемые свойства

    Я думал, что, возможно, атомарные свойства будут полезны для избежания блокировок при работе с неизменяемыми объектами, но поскольку неизменяемые объекты могут указывать на изменяемые объекты в Objective-C это не очень помогает:

    @interface SlightlySaferObject : NSObject {}
    
    @property (atomic, readwrite) NSArray *stuff;
    
    @end
    
    void doStuffWith(SlightlySaferObject *obj) {
        [[obj.stuff objectAtIndex:0] mutateLikeCrazy];//not at all thread-safe without a lock
    }
    

    Единственные сценарии, которые я могу придумать, когда безопасно использовать атомарные аксессоры без блокировки (и, следовательно, вообще стоит использовать атомарные свойства):

    1. Работа с свойства, которые Мой вопрос: не являются ли атомарные свойства избыточными в большинстве сценариев параллелизма? Например:

      Сценарий 1: изменяемые свойства

      @interface ScaryMutableObject : NSObject {}
      
      @property (atomic, readwrite) NSMutableArray *stuff;
      
      @end
      
      void doStuffWith(ScaryMutableObject *obj) {
          [_someLock lock];
          [obj.stuff addObject:something]; //the atomic getter is completely redundant and could hurt performance
          [_someLock unlock];
      }
      
      //or, alternatively
      void doStuffWith(ScaryMutableObject *obj) {
          NSMutableArray *cachedStuff = obj.stuff; //the atomic getter isn't redundant
          [_someLock lock];
          [cachedStuff addObject:something]; //but is this any more performant than using a nonatomic accessor within the lock?
          [_someLock unlock];   
      }
      

      Сценарий 2: неизменяемые свойства

      Я думал, что, возможно, атомарные свойства будут полезны для избежания блокировок при работе с неизменяемыми объектами, но поскольку неизменяемые объекты могут указывать на изменяемые объекты в Objective-C это не очень помогает:

      @interface SlightlySaferObject : NSObject {}
      
      @property (atomic, readwrite) NSArray *stuff;
      
      @end
      
      void doStuffWith(SlightlySaferObject *obj) {
          [[obj.stuff objectAtIndex:0] mutateLikeCrazy];//not at all thread-safe without a lock
      }
      

      Единственные сценарии, которые я могу придумать, когда безопасно использовать атомарные аксессоры без блокировки (и, следовательно, вообще стоит использовать атомарные свойства):

      1. Работа с свойства, которые примитивы;
      2. Работа со свойствами, которые гарантировано быть неизменным и не чтобы указать на изменяемые объекты (например, NSString или NSArray из неизменяемые объекты)

      Я что-то упустил? Есть ли другие веские причины использовать атомарные свойства?

6
задан Community 23 May 2017 в 11:44
поделиться