#iphone #objective-c #memory-management #memory-leaks
#iPhone #objective-c #управление памятью #утечки памяти
Вопрос:
Я смотрю на чей-то код и знаю, что общее правило таково: если у вас есть alloc / init, вам нужно освободить эту память. Он использует множество NSMutableArrays, выделяет / инициализирует их, но не освобождает. Могу ли я просто отправить сообщение об авторелизе в массив, который создается, если я не вижу, чтобы какое-либо другое сообщение о выпуске / авторелизе отправлялось в этот массив? Я в принципе тоже не хочу, чтобы его код зависал и переставал работать: P.
С NSMutableArrays, когда вы отправляете сообщение AddObject и объект в этом массиве увеличивает свою учетную запись сохранения, если этот массив освобождается, но объекту никогда не отправляется release или removeObject из массива, это тоже утечка памяти? Спасибо.
Ответ №1:
Вам нужно либо -release
, либо -autorelease
что угодно, что вы -retain
, alloc
, -copy
allocWithZone:
или -copyWithZone:
. (И, если вы сохраняете что-то дважды, вам также нужно дважды освободить это.)
Когда объект NSMutableArray
(или NSArray
, NSSet
NSDictionary
и изменяемые подклассы) освобождается (количество сохранений достигает нуля), он освобождает все, что он содержит. Когда вы добавляете объект в NSMutableArray
, массив сохраняет объект (он не копирует его, как утверждают некоторые люди).
Я настоятельно рекомендую Руководство по программированию управления памятью как вам, так и кому-то, на кого вы ссылались в вопросе.
Я надеюсь, что этот ответ поможет вам и кому-то еще. Удачи. 🙂
Кроме того, включите статический анализатор Clang в настройках сборки. Это сообщит вам во время компиляции, когда произойдет утечка (и многое, многое другое). На самом деле, это первое, что я всегда делаю, когда начинаю новый проект. Анализатор никогда не лгал мне.
Ответ №2:
NSArray
и NSMutableArray
освобождают все свои объекты, когда они уничтожаются, поэтому, если массив управляется должным образом с помощью retain
и release
(или autorelease
), объекты внутри не будут потеряны. Но если есть массивы, которые никогда не будут выпущены, они будут протекать вместе со всем, что внутри них.
Не видя кода, трудно выступать за простое добавление autorelease
s повсюду, но для массивов, которые используются только в контексте одной функции (и не назначаются ivars или статическим переменным), ответ — да, они должны быть autoreleased
. Или, выражаясь более идиоматично, создайте их с помощью таких методов, как arrayWithCapacity
, которые возвращают объект, который уже был добавлен в пул автоматического выпуска.
Ответ №3:
Обычно освобождаются все объекты, которые вы инициализируете. Но в вашем случае освобождение массива также должно освободить все объекты.
Но все зависит от того, как вы используете свои объекты!!!