Мы знаем о полном шаблоне alloc / init, что alloc и init должны быть объединены.
NSObject *myObj = [[NSObject alloc] init];
1- Метод init получает объект от другого источник (не из выделения, новый, копировать или аналогично или сохранять), поэтому согласно фундаментальному правилу управления памятью он не является владельцем и не должен выпускать его. Однако в статье «Распределение и инициализация объектов / возвращенный объект» говорится, что init может освободить получателя.
Как это могло быть возможно, когда он против основное правило?
2- Кроме того, из той же статьи init может возвращать другой объект или nil. Итак, в этом случае, когда мы используем полный шаблон alloc / init, мы не могли освободить объект, возвращенный функцией alloc, но мы могли только освободить объект, возвращенный из init, а init освобождает объект, полученный от alloc, вместо нас.
Но init не является распределением, новый,
Размещение и инициализация объектов / возвращенный объект:
Однако в некоторых В некоторых случаях эта ответственность может означать возврат объекта, отличного от получателя. Например, если класс хранит список именованных объектов, он может предоставить метод initWithName: для инициализации новых экземпляров. Если на одно имя может быть не более одного объекта, initWithName: может отказаться назначать одно и то же имя двум объектам. Когда его просят присвоить новому экземпляру имя, которое уже используется другим объектом, он может освободить только что выделенный экземпляр и вернуть другой объект - таким образом, гарантируя уникальность имени и в то же время предоставляя то, что был запрошен экземпляр с запрошенным именем.
В некоторых случаях метод init ... может не выполнить то, что его просят. Например, метод initFromFile: может получить необходимые данные из файла, переданного в качестве аргумента. Если переданное имя файла не соответствует фактическому файлу, он не сможет завершить инициализацию. В таком случае метод init ... может освободить получателя и вернуть nil , указывая, что запрошенный объект не может быть создан.
Поскольку метод init ... может вернуть объект, отличный от вновь выделенного получателя, или даже вернуть nil , . Важно, чтобы программы использовали значение, возвращаемое методом инициализации, а не только то, которое возвращается функцией alloc или allocWithZone:. Следующий код очень опасен, так как он игнорирует возврат init.
id anObject = [SomeClass alloc];
[инициализация объекта];
[anObject someOtherMessage];
Вместо этого, чтобы безопасно инициализировать объект, вы должны объединить сообщения выделения и инициализации в одной строке кода.
id anObject = [[SomeClass alloc] init];
[anObject someOtherMessage];