Метод init
не получает объект;объект получает сообщение init
.Объект не обладает собой;скорее, он всегда знает о себе (через неявный аргумент self
в каждом сообщении).
Вы правы в том, что объект сам по себе не принадлежит.Если бы alloc
и init
были объединены в одном методе new
, этот метод был бы его собственным (super
) вызывающим объектом, поэтому он будет владеть объектом (до тех пор, пока он не вернется) и, таким образом, будет безусловно прав в его освобождении,Поскольку они отделены друг от друга и init
не является вызывающей стороной alloc
, вы правы в том, что он не владеет объектом, поэтому вы правы, ставя под сомнение эту практику.
Это один изнесколько случаев, когда один объект может освободить объект (в данном случае сам) от имени другого.Альтернативой является не выпускать его, что, если вы собираетесь либо вернуть nil
, либо выбросить исключение, будет утечкой.
В общем, всякий раз, когда у вас есть объект, сохраняющий или выпускающий себя,ты должен чувствовать себя грязным. В данном конкретном случае , все в порядке, потому что вы скорее предотвращаете ошибку (утечку), чем, возможно, ее создаете.
2 - Также из той же статьи init можетвернуть другой объект или ноль.Таким образом, в этом случае, когда мы используем полный шаблон alloc / init, мы не можем освободить объект, возвращенный alloc, но мы можем только освободить объект, возвращенный из init, и init освобождает объект, полученный от alloc вместо нас.
Но init - это не метод alloc, new, copy или подобное, поэтому мы не должны освобождать возвращаемый из него объект, поскольку он не дает нам права собственности на объект.
Asinit
освобождает старый объект от имени своего вызывающего, если он создает новый объект, он делает это от имени своего вызывающего.Вызывающий объект владеет замещающим объектом, который init
создает или извлекает для него.
В качестве следствия этого, если init
возвращает ранее существующий объект, он должен сохранить его, чтобы вызывающий владелit.
Снова исследуя гипотетический метод * new
, необходимо также освободить старый объект и создать (собственно) или сохранить замену.
Во всех этих случаяхinit
действует от имени своего абонента.Обычно для одного метода сложно управлять другим, но для этих случаев необходимо init
делать это от имени вызывающей стороны.
* Метод new
существует, но просто отправляет alloc
и init
, поэтому нет необходимости реализовывать это отдельно.