Как лучше всего использовать свойства Obj-C 2.0 с изменяемыми объектами, такими как NSMutableArray?

У меня есть класс Obj-C 2.0 со свойством NSMutableArray. Если я использую следующий код, то синтезированный сеттер предоставит мне неизменяемую копию, а не изменяемую:

@property (readwrite, copy) NSMutableArray *myArray;

Есть ли причина, по которой Apple не реализовала следующий синтаксис?

@property (readwrite, mutablecopy) NSMutableArray *myArray;

Поскольку у нас нет mutablecopy, как лучше всего справиться с этой (казалось бы, распространенной) ситуацией? Должен ли я просто написать свой собственный сеттер, который выполняет -mutableCopy?


person Nick Forge    schedule 03.05.2009    source источник


Ответы (6)


Как было сказано ранее, правильный способ сделать это - не превращать изменяемый массив в свойство. Там отличное объяснение того, что вы должны реализовать, чтобы быть совместимым с KVC здесь.

person wbyoung    schedule 03.05.2009
comment
В этом ответе stackoverflow.com/a/14814973/104790 я представляю решение, которое предоставляет изменяемые коллекции без нарушения инкапсуляции. Ответ здесь не подходит для этого вопроса, потому что он предназначен только для readonly свойств. - person Nikolai Ruhe; 11.02.2013
comment
Вот рабочая ссылка на ответ Николая: stackoverflow.com/a/14814973/1687195 - person user1687195; 29.12.2015

Некоторое время назад я столкнулся с той же проблемой и обнаружил документ по Apple Developer Connection, в котором рекомендуется предоставить собственную реализацию установщика. Пример кода из связанного документа:

@interface MyClass : NSObject {
    NSMutableArray *myArray;
}
@property (nonatomic, copy) NSMutableArray *myArray;
@end

@implementation MyClass

@synthesize myArray;

- (void)setMyArray:(NSMutableArray *)newArray {
    if (myArray != newArray) {
        [myArray release];
        myArray = [newArray mutableCopy];
    }
}
person Markus Müller-Simhofer    schedule 03.05.2009

В Какао не принято передавать NSMutableArrays. Стандартная практика Какао заключалась бы в реализации кодирования "ключ-значение", совместимого с методы для свойства, индексированного для многих. Это дает два преимущества:

  1. Наблюдение за ключом и значением работает, как ожидалось (есть несколько случаев, когда наблюдение за NSMutableArray приводит к поведению «не то, что вы хотите»)
  2. Реализация вашей структуры данных скрыта, потому что вы предоставляете изменяющие методы (например, -[MyObject insertObjectInMyProperty:(id)newObject atIndex:(NSUInteger)i], а не саму структуру данных.
person Barry Wark    schedule 03.05.2009

Имейте в виду, что передача изменяемого массива на самом деле не является обычной практикой в ​​Какао. Вы можете использовать частный изменяемый массив в качестве внутреннего хранилища, но создавать методы с использованием простых объектов NSArray для добавления или извлечения объектов из него. Возможно, поэтому нет объявления свойства mutablecopy.

person Marc Charbonneau    schedule 03.05.2009

Вам придется написать свой собственный сеттер.

person Becca Royal-Gordon    schedule 03.05.2009

Правильный способ удержать NSMutableArray - это сохранить свойство:

@property (nonatomic, retain) NSMutableArray *myArray;

Вам не нужно писать собственный сеттер или использовать копию. Свойство копирования следует использовать с массивом NSArray, который действительно нужно копировать, когда свойство захватывается в другой объект. Например, если вы назначаете объект NSMutableArray свойству типа NSArray со свойством copy, вы действительно хотите сделать копию изменяемого массива, чтобы «захватить» его как неизменное свойство с этого момента.

И у Марка правильный подход: обычно NSMutableArray не входит в состав общедоступного API ваших объектов. Если у вас есть общедоступное свойство, это может быть NSArray со свойством copy.

person MoDJ    schedule 17.06.2013