#objective-c
#objective-c
Вопрос:
Например ;
TheClass * aInstance = [[TheClass alloc] init];
TheClass * bInstance;
bInstance = aInstance;
[bInstance release]
Будет ли в этом случае освобождена память, выделенная aInstance?
Ответ №1:
Да, это было бы возможно, потому что существует только один экземпляр — у вас просто есть два разных указателя на него.
Как и в обычном C, присвоение адреса (указателя) для некоторого объекта различным переменным не имеет отношения к фактическому выделению памяти, используемой для этого объекта. В Objective-C применяется та же концепция. Если вы хотите «сохранить» две разные ссылки на один объект, вам нужно, чтобы обе ссылки «владели» им. В этом случае это было бы путем наличия второй ссылки retain
на объект, вероятно, потому, что вы сохраняете его в переменной экземпляра и т.д.
Ответ №2:
ДА.
Похоже, вы немного сбиты с толку происходящим, поэтому я объясню пару вещей:
- Память не была выделена
aInstance
. Это просто место в памяти, которое содержит число. Память фактически была выделенаTheClass
классом. - Метод выделения выделил фрагмент памяти в совершенно отдельном разделе памяти и вернул местоположение этого фрагмента в качестве результата метода.
aInstance
просто сохраняет это местоположение (которое является большим числом). Вот и все. Это число интерпретируется как указатель (т. Е. Ссылка на другое местоположение в памяти), но это не обязательно. Вы могли бы использовать его как int, если вам хочется приключений.- Когда вы делаете:
bInstance = aInstance;
, вы просто копируете это число из одного слота памяти в другой. Вы ничего не делаете со ссылкой на объект с помощью этой переменной. Вы просто дублируете уже существующий указатель. - Когда вы освобождаете объект, он будет освобожден, потому что им владеет только одна вещь (вы, вызывая метод выделения).
- Освобождение объекта ничего не делает с объектами, которые ссылались на него, поэтому ваши переменные по-прежнему будут содержать теперь уже бывший адрес в памяти, где раньше жил объект. Другими словами, это «висячие» или «устаревшие» указатели, и рекомендуется обнулить их (присвоив им
nil
).
Фух, это слишком большой набор текста для клавиатуры iPhone. 😛
Ответ №3:
Да, он будет освобожден, и ни один из них не aInstance
не bInstance
следует безопасно использовать после выпуска.
Ответ №4:
TheClass * aInstance = [[TheClass alloc] init]; //retain count = 1
TheClass * bInstance; //this is a pointer so retain count remain 1
bInstance = aInstance; //the pointer refer to the instance (retain count =1)
[bInstance release] //release => retain count =0, object released
Ответ №5:
Да, он будет освобожден.
Если вы замените «bInstance = aInstance;» на:
bInstance = [aInstance сохранить];
это не освободит память, пока вы не освободите ее еще раз. Хотя вы можете захотеть использовать авторелиз для краткосрочного использования.
Ответ №6:
ДА. Вы инициализировали его только один раз и выпустили только один раз. Таким образом, количество сохранений равно 0.
Правила таковы:
- alloc устанавливает количество сохранений равным 1
- Вызов «сохранить» увеличит количество сохранений на 1
- Вызов «release» уменьшит количество сохранений на 1
- Если значение retaincount после выпуска равно 0, объект удаляется.
Комментарии:
1. -1
init
не имеет никакого отношения к влиянию на владение объектом. Перейдите и перечитайте правила управления памятью.2.
alloc
не обязательно устанавливать счетчик сохранения равным 1. Максимум, что вы можете заключить, это то, что это увеличивает количество сохранений на 1.3. И думать об этом в терминах количества сохранений некорректно (даже относительное количество сохранений). Не думайте об этом как об «увеличении количества сохранений на 1», а вместо этого как о «провозглашении права собственности на объект», «отказе от права собственности на объект» и т.д.