copyWithZone установка переменных экземпляра? - PullRequest
9 голосов
/ 06 января 2010

Является ли copyWithZone (см. Ниже) правильным, особенно тот бит, в котором я использую установщики для заполнения переменных экземпляра нового объекта?

@interface Planet : NSObject <NSCopying>
{
    NSString *name;
    NSString *type;
    NSNumber *mass;
    int index;
}
@property(copy) NSString *name;
@property(copy) NSString *type;
@property(retain) NSNumber *mass;
@property(assign) int index;
-(void)display;
@end

-(id) copyWithZone: (NSZone *) zone {
    Planet *newPlanet = [[Planet allocWithZone:zone] init];
    NSLog(@"_copy: %@", [newPlanet self]);
    [newPlanet setName:name];
    [newPlanet setType:type];
    [newPlanet setMass:mass];
    [newPlanet setIndex:index];
    return(newPlanet);
}

EDIT_001:

Это лучший способ?

-(id) copyWithZone: (NSZone *) zone {
    Planet *newPlanet = [[[self class] allocWithZone:zone] init];
    [newPlanet setName:[self name]];
    [newPlanet setType:[self type]];
    [newPlanet setMass:[self mass]];
    [newPlanet setIndex:[self index]];
    return(newPlanet);
}

большое спасибо

1011 * Гэри *

Ответы [ 3 ]

6 голосов
/ 11 июля 2012

(Предполагая, что вам нужна глубокая копия) для копии, которую мы хотим сделать, используйте copyWithZone: для переменных экземпляра объекта и просто установите примитивные переменные экземпляра, используя =.

- (id)copyWithZone:(NSZone *)zone
{
    MyClass *copy = [[MyClass alloc] init];

    // deep copying object properties
    copy.objectPropertyOne = [[self.objectPropertyOne copyWithZone:zone] autorelease];
    copy.objectPropertyTwo = [[self.objectPropertyTwo copyWithZone:zone] autorelease];
                  ...
    copy.objectPropertyLast = [[self.objectPropertyLast copyWithZone:zone] autorelease];

    // deep copying primitive properties
    copy.primitivePropertyOne = self.primitivePropertyOne
    copy.primitivePropertyTwo = self.primitivePropertyTwo
                  ...
    copy.primitivePropertyLast = self.primitivePropertyLast

    // deep copying object properties that are of type MyClass
    copy.myClassPropertyOne = self.myClassPropertyOne
    copy.myClassPropertyTwo = self.myClassPropertyTwo
                  ...
    copy.myClassPropertyLast = self.myClassPropertyLast


    return copy;
}

Но обратите внимание, как свойства того же класса, что и self и copy, должны быть установлены без copyWithZone :. В противном случае эти объекты снова вызовут этот copyWithZone и попытаются установить свои myClassProperties, используя также copyWithZone. Это вызывает нежелательный бесконечный цикл. (Кроме того, вы можете вызвать allocWithZone: вместо alloc: но я уверен, что alloc: вызывает allocWithZone: в любом случае)

В некоторых случаях использование = для глубокого копирования свойств объекта одного и того же класса может быть не тем, что вы хотите делать, но во ВСЕХ СЛУЧАЯХ (насколько я знаю) глубокое копирование свойств объекта одного и того же класса с помощью copyWithZone: или все, что вызывает copyWithZone: приведет к бесконечному циклу.

3 голосов
/ 06 января 2010

Вы прочитали это руководство ? Если это так, вы должны выбрать, хотите ли вы мелкую или глубокую копию. Для мелких копий вы можете использовать общие значения: это типичный подход при реализации подкласса NSCell , который использует экземпляр NSImage .

Поскольку я не знаю контекста, я скажу, что ваша реализация кажется правильной.

3 голосов
/ 06 января 2010

Независимо от того, является ли это нежелательной копией, решать вам. Причиной синтеза средств доступа с квалификатором копирования является уверенность в принадлежности этих объектов.

Имейте в виду, однако, что неизменные объекты, такие как NSNumber или NSString, на самом деле не будут дублировать свое хранилище при отправке сообщения -copy, они просто увеличат количество сохраняемых элементов.

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