выделить и инициализировать, что они на самом деле делают - PullRequest
24 голосов
/ 03 октября 2010

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

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

Ответы [ 5 ]

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

    MyClass* myObj = [MyClass alloc];
    

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

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

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

3 голосов
/ 03 октября 2010

В простейшем виде:

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

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

-

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

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

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

  return self;
}
1 голос
/ 03 октября 2010

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
0 голосов
/ 15 мая 2017

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

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

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

недостаточно для полной инициализации объекта.

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

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

    ClassName * objectName = [ClassName alloc] init];

от: яблочные документы

0 голосов
/ 28 марта 2014

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

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