Кто отвечает за освобождение объектов массива при копировании?

StackOverflow https://stackoverflow.com/questions/1087689

Вопрос

Если в Objective-C массив1 копируется в массив2 с помощью mutableCopy и предположим, что код выполняется в функции main(), кто отвечает за освобождение объектов, содержащихся в массиве?Это main() или array2?

Это было полезно?

Решение

Я думаю, что предыдущие ответы упустили суть, или же автор вопроса был довольно неясен.Фактический вопрос касается не какого-либо массива, а скорее содержимого массива:

кто несет ответственность за выпуск объекты, содержащиеся в массиве?Это main() или array2?

Оба array1 и array2 несут ответственность за освобождение объектов.

Из Документация НСаррай:

«Массивы поддерживают строгие ссылки на свое содержимое — в среде управляемой памяти каждый объект получает сообщение сохранения перед добавлением его идентификатора в массив и сообщение освобождения, когда он удаляется из массива или когда массив освобождается».

Начнем с того, что каждый из объектов сохраняется в NSArray. array1.Когда вы создаете array2 с помощью -mutableCopy, вы получаете NSMutableArray, который указывает на одни и те же объекты и снова сохраняет каждый из них.Если бы вы выпустили array1 в этот момент, когда это dealloc был вызван метод, он освободил бы каждый из содержащихся в нем объектов.Однако, array2 сохранил их, поэтому объекты не будут уничтожены — только тогда, когда их счетчик сохранения достигнет 0, что произойдет, если array2 были уничтожены, и никто больше не сохранил ни одного из объектов (или когда они были удалены из array2).

Поскольку классы коллекций (массивы, наборы, словари и т. д.) управляют сохранением и освобождением их содержимого, все, о чем вам нужно беспокоиться, — это сохранение или освобождение самой коллекции.Поскольку вы использовали -mutableCopy, помните, что вы неявно сохранили array2, поэтому вам следует отпустить его, когда закончите с ним.

Другие советы

Я ссылаюсь это руководство для управления памятью в Obj-C.У него есть раздел «Массивы и словари», вот отрывок:

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

Комментарии к публикации также будут полезны

Обязанности владения не изменяются при хранении объектов в массиве.Вот пример:

int main(int argc, char *argv[])
{
    // ...

    NSObject *obj1 = [[NSObject alloc] init]; // owned
    NSObject *obj2 = [[NSObject alloc] init]; // owned
    NSObject *obj3 = [[[NSObject alloc] init] autorelease]; // not owned

    NSMutableArray *array1 = [NSMutableArray arrayWithObjects: obj1, obj2, obj3, nil]; // not owned
    NSMutableArray *array2 = [array1 mutableCopy]; // owned

    // ...

    [array2 release];
    [obj2 release];
    [obj1 release];

    // ...
}

Этот код напрямую выделяет obj1 и obj2, поэтому он владеет ими и должен их освободить, но освобождает автоматически obj3, поэтому его не обязательно выпускать.Точно так же он не владеет результатом arrayWithObjects:, поэтому он не освобождает это, но владеет результатом mutableCopy, поэтому он должен это выпустить.Объекты, хранящиеся в массиве, не имеют значения: все, что вам нужно, — это право собственности.

Оба массива сохраняют строгие ссылки на свое содержимое, поэтому obj1, obj2, и obj3 не будет освобождено, пока существуют массивы, но это деталь NSArray контракт, это не влияет на то, как вы управляете владением объектами или массивами.

Это все детали Соглашения об управлении памятью Cocoa, а не массивы.

Было бы бессмысленно привязывать изменяемый массив к неизменяемому массиву.main() будет отвечать за освобождение массива array1.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top