#objective-c
#objective-c
Вопрос:
Что произойдет, если вы добавите только что созданный объект в изменяемый массив и освободите свой объект?
Ответ №1:
Это зависит. Если вы владели объектом до добавления его в массив, вы все равно должны освободить свое собственное заявление о праве собственности, чтобы избежать утечки — заявление о праве собственности массива на объект является отдельным и не освобождает вас от вашей собственной ответственности в отношении правил управления памятью.
Object *obj = [[Object alloc] init];
[anArray addObject:obj];
[obj release];
С другой стороны, если вы не были владельцем объекта, то вы все еще не являетесь им после добавления в массив и по-прежнему не должны его освобождать. Массив устанавливает свое собственное требование владения, но, как и ваш собственный код, он отвечает за балансировку своих собственных требований.
Object *obj = [Object object];
[anArray addObject:obj];
// or, avoiding a temp variable
[anArray addObject:[Object object]];
Когда вы освободите массив или удалите объект из массива (предполагая, что это изменяемый массив), массив выпустит свое собственное заявление о праве собственности. Вызывающий код не несет дополнительной ответственности за это — массив сделал заявку на владение, поэтому он отвечает за ее освобождение, когда это будет сделано с объектом.
Другими словами, ваша ответственность за освобождение объекта или нет не имеет ничего общего с тем, добавили ли вы его в коллекцию. Ответственность массива также не имеет никакого отношения к тому, что происходит за пределами массива. Это лежит в основе инкапсуляции; каждый класс максимально изолирован от того, что происходит внутри других классов. То, что происходит в NSVegas, остается в NSVegas. 🙂
Ответ №2:
Все в порядке:
NSMutableArray *array = [[NSMutableArray array] retain];
Object *obj = [[Object alloc] init];
[array addObject:obj];
[obj release];
Я создал объект с помощью alloc, init
— так что я владелец объекта. Я добавил объект в массив, и массив стал владельцем. Затем я освободил объект. Но у него все еще есть владелец — массив.
Кстати: Если вы освободите массив, объект будет освобожден автоматически.
Комментарии:
1. Обратите внимание, что, поскольку массив становится владельцем объекта, аналогичный код, создающий объект, который не принадлежит вызывающей стороне, также будет работать.
2. Также обратите внимание, что отправка
-retain
в изменяемый массив не требуется в этом конкретном фрагменте кода.3. @Bavarious: Если объект не будет принадлежать вызывающей стороне, он будет удален при вызове [obj release], потому что у него будет только 1 счетчик сохранения. В этом случае, я думаю, у вас также возникнет исключение неправильного доступа при освобождении массива.
4. Верно, я пропустил часть ‘освободить ваш объект’. Вы правы: хотя объект все еще был бы активен, потому что он принадлежит массиву, при освобождении самого массива произойдет исключение.
5. Однако суть остается в силе. Если есть удобный метод, который возвращает объект, которому никто не принадлежит, это можно было бы упростить, используя его, вплоть до просто
[array addObject:[Object object]]
. Да, вызов-release
объекта, созданного таким образом, приведет к сбою — так что не делайте этого. 🙂
Ответ №3:
Я бы выделил массив таким образом:
NSMutableArray *array = [[NSMutableArray alloc] init];
[array retain]
Object *obj = [[Object alloc] init]; //retain count = 1
При добавлении объекта количество сохраненных увеличивается до 2
[array addObject:obj];
//When you release the retain count goes to 1 (object still exists)
[obj release];
Если вы освободите массив
[array release];
затем количество объектов становится равным 0.