+initalize
отправляется в класс в первый раз, когда он или один из его подклассов получают сообщение в первый раз. Итак, когда вы делаете:
instance = [[[YourClass alloc] init] autorelease];
Это alloc
сообщение вызывает initialize
.
Если вы делаете то же самое с подклассом:
instance = [[[SubclassOfYourClass alloc] init] autorelease];
Это сообщение alloc
вызовет +[YourClass initialize]
так же, как и другое (до того, как также было вызвано +[SubclassOfYourClass initialize]
. Но это сделает только один из них - initialize
каждого класса никогда не вызывается более одного раза. (Если вы сами не позвоните с помощью [super initialize]
или [SomeClass initialize]
- не делайте этого, потому что метод не будет этого ожидать).
-init
, с другой стороны, инициализирует новый экземпляр. В выражении [[YourClass alloc] init]
вы лично отправляете сообщение непосредственно в экземпляр. Вы также можете вызвать его косвенно, через другой инициализатор ([[YourClass alloc] initWithSomethingElse:bar]
) или фабрику удобства ([YourClass instance]
).
В отличие от initialize
, вы всегда должны отправлять init
(или другой инициализатор, если уместно) вашему суперклассу. Большинство методов инициализации выглядят примерно так:
- (id) init {
if ((self = [super init])) {
framistan = [[Framistan alloc] init];
}
return self;
}
Детали различаются (этот метод или суперкласс или оба могут принимать аргументы, и некоторые люди предпочитают self = [super init]
в своей строке, а Уил Шипли вообще не присваивает self
), но основная идея та же: вызов [super init[WithSomething:…]]
, убедитесь, что он не вернул nil
, настройте экземпляр, если он не вернулся, и верните все, что вернул суперкласс.
Это означает, что вы можете вернуть nil
из init
, и действительно вы можете. Если вы сделаете это, вы должны [self release]
, чтобы не допустить утечки неисправного объекта. (Для обнаружения недопустимых значений аргумента альтернатива - NSParameterAssert
, которая выдает исключение, если утверждение не выполнено. Относительные достоинства каждого из них выходят за рамки этого вопроса.)
Как я могу использовать это для создания экземпляра моего AppController с переменными экземпляра, которые составляют мой интерфейс?
Лучший способ - сделать все это в main
:
int main(int argc, char **argv) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
AppController *controller = [[[AppController alloc] init] autorelease];
[[NSApplication sharedApplication] setDelegate:controller]; //Assuming you want it as your app delegate, which is likely
int status = NSApplicationMain(argc, argv);
[pool drain];
return status;
}
Вы будете выполнять любые другие настройки в методах делегата приложения в AppController
.
Вы уже знаете это, но для всех, кто читает это: Перья - ваш друг. Интерфейсный конструктор - ваш друг. Не боритесь с фреймворком - работайте с ним и постройте свой интерфейс графически, и ваше приложение будет лучше для него.