Лучшая практика для копирования частного экземпляра Вар с NSCopying

Я мог бы пропускать что-то очевидное здесь, но я реализую NSCopying на одном из моих объектов. Тот объект имеет частные переменные экземпляра, которые не выставляются через методы считывания, поскольку они не должны использоваться вне объекта.

В моей реализации copyWithZone:, Я нуждаюсь в alloc/init новый экземпляр, но также и настраиваю его состояние для соответствия текущему экземпляру. Я могу, очевидно, получить доступ к текущему частному состоянию изнутри copyWithZone:, но я не могу установить его в новый объект, потому что нет никаких средств доступа для того состояния.

Существует ли стандартный путь вокруг этого при тихом сохранении конфиденциальности данных в целости?

Спасибо.

10
задан Ben Zotto 2 April 2010 в 15:10
поделиться

3 ответа

Во-первых, у вас всегда должны быть геттеры, даже если они частные. Ваш объект должен получать доступ даже даже к своим собственным ivars с помощью аксессоров (за исключением очень небольшого числа случаев). Это избавит вас от многих страданий, связанных с управлением памятью.

Во-вторых, предложение Алекса использовать -> является стандартным подходом, даже несмотря на то, что это нарушает приведенное выше правило геттеров. Есть небольшое количество исключений из этого правила, и копия - одно из них. Использование частных сеттеров здесь по-прежнему разумно (и раньше я делал это исключительно), но по разным причинам я обнаружил, что использование -> часто работает более чисто.

Будьте очень осторожны, чтобы правильно управлять памятью. Если вам нужно вызвать [super copyWithZone:] , то вам также следует ознакомиться со сложностями NSCopyObject () и тем, как он влияет на вас, даже если вы не используете его сами. . Я подробно обсуждал это в «NSCopyObject () считается вредоносным».

8
ответ дан 3 December 2019 в 23:12
поделиться

Вы можете получить прямой доступ к переменным экземпляра копии. Для этого используется тот же синтаксис разыменования указателей, что и в случае со структурой. Так, например, если ваш класс такой:

@interface MyCopyableClass : NSObject {
    int anInstanceVariable;
}
@end

Вы можете сделать так:

- (id)copyWithZone:(NSZone *)zone {
    MyCopyableClass *theCopy = [[[self class] allocWithZone:zone] init];
    theCopy->anInstanceVariable = anInstanceVariable;
    return theCopy;
}
5
ответ дан 3 December 2019 в 23:12
поделиться

Один из вариантов - создать собственный инициализатор, который принимает частные значения iVar. Таким образом, вы создаете его так:

-(id) initWithPropertyOne:(SomeClass *) anObject andPropertyTwo:(SomeClass *) anotherObject;

Когда вы создаете копию, просто используйте специальный инициализатор.

1
ответ дан 3 December 2019 в 23:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: