Подтвердить что ты не робот

Распределять и инициализировать то, что они на самом деле делают

Может кто-нибудь объяснить мне, что init и alloc делают в Obj-C. Я читаю эту книгу obj-c, которая дает пример создания объекта, но на самом деле он не вникает в детали того, что он делает. Что возвращает alloc? что возвращает init?

Animal * k = [Animal alloc];
k = [k init];
4b9b3361

Ответ 1

  • alloc выделяет кусок памяти для хранения объекта и возвращает указатель.

    MyClass* myObj = [MyClass alloc];
    

    myObj пока не используется, поскольку его внутреннее состояние неправильно настроено. Итак, не пишите такой код.

  • init устанавливает начальное условие объекта и возвращает его. Обратите внимание, что то, что возвращается [a init] , может отличаться от a. Это объясняет код Yannick:

    -init{
         self=[super init]; // 1.
         if(self){          // 2.
             ....
         }
         return self;       // 3.
    }
    
    • Сначала вам нужно вызвать суперкласс init, чтобы настроить переменные экземпляра суперкласса и т.д. Это может вернуть что-то, не равное оригиналу self, поэтому вам нужно назначить то, что вернулось в self.
    • Если self не равно nil, это означает, что часть, управляемая суперклассом, была правильно инициализирована. Теперь вы выполняете свою инициализацию. Все переменные экземпляра устанавливаются на nil (если он объект) и 0, если он целочисленный. Вам нужно будет выполнить дополнительные начальные настройки.
    • Верните настройки self. Возвращенный self может отличаться от выделенного! Таким образом, вам нужно присвоить результат init вашей переменной.

Это важный урок: никогда не разбивайте вызов на alloc и init. Не пишите:

 MyClass* myObj = [MyClass alloc];
 [myObj init];

потому что [myObj init] может вернуть что-то еще. Не пытайтесь обойти это, написав:

 MyClass* myObj = [MyClass alloc];
 myObj=[myObj init];

потому что вы в конце концов забудете записать часть myObj= во второй строке.

Всегда пишите:

 MyClass* myObj = [[MyClass alloc] init];

Я также не рекомендую писать:

 MyClass* myObj = [MyClass new];

потому что он неправильно вызывает метод инициализации: некоторые классы не принимают простой init. Например, NSView требуется initWithFrame:, который нельзя вызвать с помощью new. Поэтому не используйте new.

Ответ 2

В простейшей форме:

  • alloc: short для распределения, резервирует местоположение памяти и возвращает указатель на эту ячейку памяти. Этот указатель затем сохраняется в переменной k.

  • init: короткий для инициализации, устанавливает объект и возвращает объект. Метод init зависит от объекта, но обычно он включает отправку сообщения init в суперкласс. И если этот метод init (суперкласса) возвращает объект (но не nil), некоторые ivars могут быть настроены в зависимости от задачи этого класса.

-

Пример реализации init, класс Schedule инициализирует свои каналы ivar с помощью пустого массива. В основном, вы предоставляете объект Schedule возможность самостоятельно сортировать, чтобы он мог начать получать сообщения после его создания. Вы можете удалить инициализацию каналов из метода init, но тогда вам нужно будет проверить, нет ли канала ivar в каждом методе класса Schedule и инициализировать его, если он действительно равен нулю.

- (Schedule*)init {
  self = [super init];

  if (self) {
    channels = [[NSMutableArray alloc] initWithCapacity:0];
  }

  return self;
}

Ответ 3

alloc и init - два метода, которые унаследованы от NSObject вы можете предоставить свои собственные методы или вызвать их из NSObject

alloc выделяет память для создания нового экземпляра вашего класса (@interface) init инициализирует содержимое этого экземпляра, по умолчанию init устанавливает все значения элементов в 0/nil, но вы можете создать свой собственный метод init для настройки сделанного.

Animal * k = [[Animal alloc] init]; // creates a new Animal object

вы также можете написать

Animal * k = [Animal new]; // which would be a bit more similar to other languages

Ответ 4

Класс NSObject root предоставляет метод класса alloc alloc: резервирует ячейку памяти и возвращает указатель на эту ячейку памяти.

Метод alloc имеет еще одну важную задачу, которая заключается в том, чтобы очистить память, выделенную для свойств объектов, установив их в ноль.

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

недостаточно, чтобы полностью инициализировать объект.

Вам нужно объединить вызов alloc с вызовом init, другим методом NSObject:

  • INIT

    (ID); Метод init используется классом, чтобы убедиться, что его свойства имеют соответствующие начальные значения при создании. Правильный способ выделения и инициализации объекта состоит в том, чтобы вставить вызов alloc внутри вызова init, например:

    ClassName * objectName = [ClassName alloc] init];

from: apple documents

Ответ 5

Alloc будет выделять память для объекта, но Init помещает объект в память и устанавливает значения по умолчанию.