Может кто-нибудь сказать мне, что именно сохраняют и выпускают в target-c? - PullRequest
0 голосов
/ 09 ноября 2011

У меня есть некоторая путаница по поводу сохранения и освобождения переменной.

Это мой вопрос:

  1. Мне выделен объект A
    Object *A = [[Object alloc] init]

    Увеличивает ли это счет удержания? Это то же самое, что иметь
    Object *A = [[[Object alloc] init] retain].
    Я знаю, что если мы вызовем retain, объект будет удерживаться, пока мы его не отпустим.


  2. 2.1. У меня есть Object A. Это Object A было передано функции в качестве аргумента. Позже в функции я выпустил его. Это освободит память о Object A? если это так, Object A больше не существует.

    2,2 Продолжайте с 2.1, вместо выпуска Object A. Я создал локальную переменную Object *B = A. Если я выпустил Object B, он также выпустит Object A. Или, если я оставлю B, он также сохранит A.

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

Спасибо

Ответы [ 4 ]

2 голосов
/ 09 ноября 2011

Object * A = [[Object alloc] init] Увеличивает ли это количество хранения?

Да, более конкретно, вероятно, он инициализирует счет удержания равным 1.

Это то же самое, что сохранить Object * A = [[Object alloc] init]]. Я знаю, что если мы вызовем retain, объект будет удерживаться до тех пор, пока мы его не отпустим.

Не то же самое. Это увеличит количество сохраняемых кадров в два раза. Нет особой причины увеличивать счет дважды в одном и том же месте. Если бы вы это сделали, вы бы ответили за то, что дважды позвонили в релиз.

У меня есть оставленный объект A. Этот объект A был передан функции в качестве аргумента. Позже в функции я выпустил его. Это освободит память об объекте А? если это так, объект А больше не существует.

Во-первых, вы должны убедиться, что понимаете, освобождает ли релиз память или нет, зависит от того, есть ли другие владельцы, которые имеют ссылку на объект. Если объект сохранился более чем одной вещью, то освобождение не освободит память в этом случае.

Во-вторых, плохая идея. Чтобы сохранить здравомыслие при подсчете ссылок, вы должны следовать определенным схемам.

  1. сохранить (или выделить) переменные экземпляра, освободить их в dealloc или ранее.
  2. при необходимости сохраните (или выделите) локальные переменные и освободите их перед выходом из метода.
  3. Вызывающая сторона не владеет возвращаемым значением функции. Это подразумевает, что вы обрабатываете возвращаемое значение функции, как локальную переменную, но автоматически освобождаете его, прежде чем возвращать, а не освобождать. Это гарантирует, что оно продлится, по крайней мере, достаточно долго, чтобы вызывающий мог сохранить его, если это необходимо.

Один из шаблонов не для вызывающего метода, чтобы иметь ссылку на аргумент метода, но когда функция возвращает, вызывающий не владеет ссылкой. Метод не должен освобождать ссылку вызывающей стороны.

Следуйте 2.1, вместо освобождения Object A. Я создал локальную переменную Object * B = ObjectA. Если я выпустил B, он также выпустит Объект A. Или, если я оставлю B, он также сохранит A.

retain и release отправляются объектам, а не ссылкам. A и B относятся к одному и тому же объекту, поэтому для одного и того же вызова сохраняются или освобождаются вызовы, как и для другого.

Допустимо, но, вероятно, нет необходимости, [B retain] и позже тем же способом [B release]. Но не делайте только [B release], тем самым экспроприируя право собственности А. на объект.

2 голосов
/ 09 ноября 2011

Запомните: NARC.

New, Alloc, Retain, Copy - это 4 команды, которые увеличивают количество сохраняемых файлов.Другими словами, для каждого NARC вам необходим соответствующий выпуск для освобождения этой памяти.

2 голосов
/ 09 ноября 2011

Вызов alloc (или new) увеличивает счет удержания.Если после этого вы снова retain, это снова увеличится.Нет необходимости делать это второе сохранение, за исключением определенных разыскиваемых дел.

Основное правило: то, что alloc, это то, что release.Конечно, вы можете обойти это, если вы действительно знаете, что делаете.

У меня есть оставленный объект A. Этот Объект A был передан функции в качестве аргумента.Позже в функции я выпустил его.Освободит ли она память об объекте А?

В принципе, да.

, если это так, объект А больше не существует.

Да, опять же, но иногда он остается «в памяти», поэтому вызовы к нему могут работать очень-очень короткое время.Очень короткий.

Далее с 2.1 вместо освобождения объекта А. Я создал локальную переменную Object * B = ObjectA.Если я выпустил B, он также выпустит Объект A. Или, если я оставлю B, он также сохранит A.

, если вы сохраните B, тогда ссылки на объекты с помощью A сохраняются дважды.поэтому освобождение B не освобождает объект, на который ссылается A. Но если вы не сохраняете B, то освобождение B равняется освобождению A (только один счет удержания).

Tip

Представьте себе, что любая ссылка, которую вы объявляете (Balloon * веревка), является веревкой, которую вы получаете в руке, чтобы сохранить объект Balloon, содержащий вещи.Веревка не является объектом.Объект (воздушный шар) создается где-то в памяти (здесь, в космосе).Если вы сохраните во второй раз, вы получите другую веревку к этому воздушному шару и получите его в другой руке.Чтобы освободить воздушный шар, вам нужно освободить обе веревки.

Обратите внимание, что alloc (или new) создает веревку, поэтому только что созданный воздушный шар не сразу попадает в космическое пространство.

Isэто ясно?

1 голос
/ 09 ноября 2011

1) init - это не то же самое, что retain.

Метод init фактически переводит объект в правильное состояние «инициализации», чтобы его можно было использовать, вызывая метод init родительских классов, а также настраивая любые дополнительные настройки, которые помещаются в метод init, реализованный в Объекты .m файл. Сохранение фактически увеличивает счет удержания на 1.

2) 2.1) Когда вы выделяете память для объекта, вы хотите освободить ее в том же объеме, скажем, поэтому, когда вы передаете объект в метод, вы не освобождаете его там. Однако, если вы выпустили его в функции / методе, в который он был передан, поскольку вы передаете ссылку на объект, он будет освобожден. Вы не можете быть полностью уверены, когда сам объект перестанет существовать.

2.2) Когда вы говорите Object *B = ObjectA, вы на самом деле не создаете другой объект, но создаете новую ссылку или указатель на ObjectA. Если вы вызываете release / retain для ссылки B, поскольку она указывает на тот же объект, что и ObjectA, это то же самое, что и вызов release / retain для ObjectA.

...