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