Объект владеет своими данными? - PullRequest
2 голосов
/ 15 декабря 2009

Как вы можете видеть из кода ниже, я создаю и инициализирую Vertex, которую затем добавляю в переменную экземпляра NSMutableArray в моем объекте Frame. Поскольку у меня есть эта настройка, myVert принадлежит main и указывает на vertexList. Буду ли я лучше настроить это так, чтобы я сделал копию inVertex в методе addVertex, чтобы объект стал владельцем своих данных?

-(void)addVertex:(Vertex*) inVertex {
    [vertexList addObject:inVertex];
}

// -------------------

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    Frame *myFrame;
    Vertex *myVert;

    NSLog(@"MDD_ObjectTest ... ");
    myFrame = [[Frame alloc] init];
    myVert = [[Vertex alloc] initWithxPos:111 yPos:222 zPos:333];

    [myFrame addVertex:myVert];
    [myVert release];

    // Clean up
    [myFrame release];
    [pool drain];
    return 0;
}

Наконец, если мне нужно сделать копию, как лучше это сделать, стоит ли мне смотреть ...

-(void)addVertex:(Vertex*) inVertex {
    [vertexList addObject:[inVertex copy]];
}

Хотя я немного не уверен, что делать с объектом Vertex в отношении copyWith Zone.

1009 * Гэри *

1 Ответ

3 голосов
/ 15 декабря 2009

Это зависит от того, является ли Vertex изменчивой или нет.

Если вершина неизменна:

Поскольку в inVertex не может быть изменено ни одного из его данных, текущий способ, которым вы располагаете, в порядке. VertexList сохранит inVertex, когда вы добавите его, и освободит его, когда вы удалите его. Поскольку свойства inVertex не могут быть изменены, нет никакой разницы в том, чтобы хранить их в сравнении с копией.

Если вершина изменчива:

Вам следует сохранить копию, чтобы изменения в inVertex не влияли на вершину, хранящуюся в списке. Однако обратите внимание, что у вас есть возможная утечка памяти, как у вас сейчас. Когда вы копируете объект, для которого для счетчика хранения установлено значение 1, то при сохранении его в vertexList счетчик хранения становится равным 2. При удалении его из списка он будет иметь счетчик хранения 1, что приведет к утечке памяти, если вы не не забудьте выпустить это. Лучшее место для его освобождения - метод addVertex после того, как он добавлен в vertexList, чтобы его счетчик оставлялся равным 1, поскольку только одна вещь имеет ссылку на него.

- (void) addVertex:(Vertex *) inVertex {
    Vertex * copy = [inVertex copy];
    [vertexList addObject:copy];
    [copy release];
}

Обратите внимание, что Vertex должен реализовать протокол NSCopying, чтобы это работало.

Я предлагаю использовать неизменный подход, если только у вас нет реальной уважительной причины сделать вершину изменчивой, кроме удобства.

Редактировать: Относительно copyWithZone:

Чтобы реализовать копирование объектов, вы должны реализовать протокол NSCopying, который определяет метод copyWithZone:. Единственное соображение, которое вам нужно сделать с зоной, заключается в том, что вместо вызова метода alloc для класса Vertex вместо этого вы вызываете allocWithZone: метод.

- (id) copyWithZone:(NSZone *) zone {
    Vertex * copy = [[Vertex allocWithZone:zone] initWithxPos:x yPos:y zPos:z];
    // Any other copying that needs to be done
    return copy;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...