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

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

@property (readwrite, copy) NSMutableArray *myArray;

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

@property (readwrite, mutablecopy) NSMutableArray *myArray;

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

Ответы [ 6 ]

14 голосов
/ 03 мая 2009

Я столкнулся с той же проблемой некоторое время назад и обнаружил документ в 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];
    }
}
5 голосов
/ 03 мая 2009

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

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

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

3 голосов
/ 03 мая 2009

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

1 голос
/ 03 мая 2009

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

0 голосов
/ 17 июня 2013

Правильный способ хранения NSMutableArray - с помощью свойства retain:

@property (nonatomic, retain) NSMutableArray *myArray;

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...