В objective-c, если на объект ссылаются более одного раза, можно ли было бы освободить его?

#objective-c

#objective-c

Вопрос:

Например ;

 TheClass * aInstance = [[TheClass alloc] init];
TheClass * bInstance;
bInstance = aInstance;
[bInstance release]
  

Будет ли в этом случае освобождена память, выделенная aInstance?

Ответ №1:

Да, это было бы возможно, потому что существует только один экземпляр — у вас просто есть два разных указателя на него.


Как и в обычном C, присвоение адреса (указателя) для некоторого объекта различным переменным не имеет отношения к фактическому выделению памяти, используемой для этого объекта. В Objective-C применяется та же концепция. Если вы хотите «сохранить» две разные ссылки на один объект, вам нужно, чтобы обе ссылки «владели» им. В этом случае это было бы путем наличия второй ссылки retain на объект, вероятно, потому, что вы сохраняете его в переменной экземпляра и т.д.

Ответ №2:

ДА.

Похоже, вы немного сбиты с толку происходящим, поэтому я объясню пару вещей:

  1. Память не была выделена aInstance . Это просто место в памяти, которое содержит число. Память фактически была выделена TheClass классом.
  2. Метод выделения выделил фрагмент памяти в совершенно отдельном разделе памяти и вернул местоположение этого фрагмента в качестве результата метода.
  3. aInstance просто сохраняет это местоположение (которое является большим числом). Вот и все. Это число интерпретируется как указатель (т. Е. Ссылка на другое местоположение в памяти), но это не обязательно. Вы могли бы использовать его как int, если вам хочется приключений.
  4. Когда вы делаете: bInstance = aInstance; , вы просто копируете это число из одного слота памяти в другой. Вы ничего не делаете со ссылкой на объект с помощью этой переменной. Вы просто дублируете уже существующий указатель.
  5. Когда вы освобождаете объект, он будет освобожден, потому что им владеет только одна вещь (вы, вызывая метод выделения).
  6. Освобождение объекта ничего не делает с объектами, которые ссылались на него, поэтому ваши переменные по-прежнему будут содержать теперь уже бывший адрес в памяти, где раньше жил объект. Другими словами, это «висячие» или «устаревшие» указатели, и рекомендуется обнулить их (присвоив им 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», а вместо этого как о «провозглашении права собственности на объект», «отказе от права собственности на объект» и т.д.