Мне интересно, какой будет правильный шаблон для реализации Mutable vs Immutable структур данных. Я понимаю концепцию и то, как она работает, но как я могу реализовать, используя базовую структуру данных Cocoa? Я имею в виду, например, если я использую NSSet
. Допустим, у меня есть следующие:Правильный шаблон для mutable vs immutable
// MyDataStructure.h
@interface MyDataStructure : NSObject
@property (nonatomic, strong, readonly) NSSet * mySet;
@end
// MyDataStructure.m
@interface MyDataStructure()
@property (nonatomic, strong) NSMutableSet * myMutableSet;
@end
@implementation MyDataStructure
- (NSSet *)mySet
{
return [_myMutableSet copy];
}
@end
Единственная причина, я использую изменяемый набор в качестве базовой структуры данных, так что изменяемые версия этого класса может искажать с ним. MyDataStructure
per se действительно не нуждается в изменяемом наборе. Поэтому, если предположить, что я реализовал несколько инициализаторов, чтобы сделать этот класс полезным, вот как MyMutableDataStructure
выглядит следующим образом:
// MyDataStructure.h (same .h as before)
@interface MyMutableDataStructure : MyDataStructure
- (void)addObject:(id)object;
@end
// MyDataStructure.m (same .m as before)
@implementation MyMutableDataStructure
- (void)addObject:(id)object
{
[self.myMutableSet addObject:object];
}
@end
Используя эту модель базовой структура данных всегда изменчива, и его неизменная версией является лишь неизменной копией (или это??).
Это также вызывает другой вопрос, возникающий при реализации протокола NSCopying
. Вот пример реализации:
- (id)copyWithZone:(NSZone *)zone
{
MyDataStructure * copy = [MyDataStructure allocWithZone:zone];
copy->_myMutableSet = [_myMutableSet copyWithZone:zone];
return copy;
}
Не copyWithZone:
вернуть неизменяемую копию, если это применимо? Поэтому я в основном присваиваю NSSet
вместо NSMutableSet
, не так ли?
Редактировать: Во время погружения в проблему я обнаружил еще несколько проблем, связанных с этой проблемой.
mySet
должен бытьcopy
вместоstrong
.- Неправильная реализация
copyWithZone:
. Я не упоминал об этом в первом сообщении, но эта реализация относится к неизменяемой версии структуры данных (MyDataStructure
). Как я уже читал, неизменяемые структуры данных фактически не создают копию, они просто возвращаются. В этом есть смысл. - Из-за 2. мне нужно было переопределить
copyWithZone:
в версии Mutable (MyMutableDataStructure
).
Чтобы сделать вещи ясно:
// MyDataStructure.h
@property (nonatomic, copy, readonly) NSSet * mySet;
И
// MyDataStructure.m
@implementation MyDataStructure
- (id)copyWithZone:(NSZone *)zone
{
// We don't really need a copy, it's Immutable
return self;
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
// I also implement -mutableCopyWithZone:, in which case an actual (mutable) copy is returned
MyDataStructure * copy = [MyMutableDataStructure allocWithZone:zone];
copy-> _myMutableSet = [_myMutableSet mutableCopyWithZone:zone];
return copy;
}
@end
@implementation MyMutableDataStructure
- (id)copyWithZone:(NSZone *)zone
{
return [self mutableCopyWithZone:zone];
}
@end
кажется сложным на первый, но я думаю, что я получаю повесить его. Таким образом, оставшиеся вопросы:
- Правильно ли шаблон?
- Получает ли getter для
mySet
измененный или неизменяемый экземпляр? - (не указано выше) Нужен ли мне сигнал
copy
при использовании атрибута свойстваcopy
?
Я ценю ваше терпение, чтобы прочесть это далеко. Лучший.
Определенно хороший ответ. Позвольте мне подробнее рассмотреть это :) –
При переопределении '-copyWithZone:' вы вызываете инициализатор '-init', а затем копируете набор. Может ли это быть реализовано как '[[[self class] allocWithZone: zone] initWithDataStructure: self]'?Кажется совершенно другим, поскольку набор не выделяется в той же зоне, но имеет ли это значение? –
Причина, по которой я говорю это, потому что я использовал 'NS_UNAVAILABLE', чтобы использовать метод' -init' ... –