В target-c, если на объект ссылаются более одного раза, можно ли его освободить? - PullRequest
3 голосов
/ 26 апреля 2011

Например;

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

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

Ответы [ 6 ]

2 голосов
/ 26 апреля 2011

Да.

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

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

Вот так много печатать на клавиатуре iPhone.: P

2 голосов
/ 26 апреля 2011

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


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

0 голосов
/ 26 апреля 2011

Да, это будет освобождено.

Если вы замените "bInstance = aInstance;" с:

bInstance = [aInstance retain];

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

0 голосов
/ 26 апреля 2011
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
0 голосов
/ 26 апреля 2011

Да, он будет освобожден, и ни aInstance, ни bInstance не следует безопасно использовать после выпуска.

0 голосов
/ 26 апреля 2011

Да.Вы только инициализировали это один раз, и только выпустили это один раз.Таким образом, количество сохранений равно 0.

Правила таковы:

  • alloc устанавливает значение хранения равным 1
  • Вызов «retain» увеличит количество сохраняемых данных с 1
  • Callng "release" уменьшит количество сохраняемых данных с 1
  • Если retaincount находится после выпуска 0, объект удаляется.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...