Какао без Interface Builder, инициализировать экземпляр контроллера приложения?

StackOverflow https://stackoverflow.com/questions/622998

Вопрос

Я не планирую писать приложения без IB, я просто пытаюсь узнать больше о программировании.

Как я могу получить один экземпляр моего класса AppController при запуске? (Обычно он загружается из пера.) И можете ли вы прояснить использование + initialize и -init ? Если я понимаю, + initialize вызывается во всех классах при запуске. Как я могу использовать это для создания экземпляра моего AppController с переменными экземпляра, которые составляют мой интерфейс?

Надеюсь, что это имеет смысл, и спасибо за любую помощь.

Это было полезно?

Решение

+ initalize отправляется в класс в первый раз, когда он или один из его подклассов получают сообщение в первый раз. Итак, когда вы делаете:

instance = [[[YourClass alloc] init] autorelease];

Это сообщение alloc вызывает initialize .

Если вы делаете то же самое с подклассом:

instance = [[[SubclassOfYourClass alloc] init] autorelease];

Это сообщение alloc будет вызывать + [YourClass initialize] так же, как и другое (до вызова + [SubclassOfYourClass initialize] . Но только один из них сделает это - initialize каждого класса никогда не будет вызываться более одного раза (если только вы сами не вызываете его с помощью [super initialize] или < code> [SomeClass initialize] & # 8212; так что не делайте этого, потому что метод этого не ожидает.)

-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: & # 8230;]] , убедитесь, что он не вернул nil , настройте экземпляр, если он не ' t и вернуть все, что вернул суперкласс.

Это подразумевает, что вы можете вернуть 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 .

Вы уже знаете это, но для всех, кто читает это: Перья - ваш друг. Интерфейсный конструктор - ваш друг. Не боритесь с фреймворком, работайте с ним и создавайте свой интерфейс графически, и ваше приложение будет лучше для него.

Другие советы

Набор NIB кажется неудовлетворительным ответом, даже если он представлен в XML (как XIB), потому что нет простого способа сравнить или объединить их с любым стандартным подрывным инструментом или инструментом в стиле SCM. Закодированная информация является хрупкой и не предназначена для редактирования простыми людьми. Как изменения будут представлены в графическом интерфейсе? Буду ли я просматривать каждый атрибут каждого элемента управления и проверять их визуально?

Однако, если поведение приложения записано в коде, есть вероятность, что я смогу понять, что происходит, даже если мне придется держать под рукой множество деталей одновременно.

Предлагаемое решение: используйте NIB верхнего уровня, который кодировал главный архитектор, а затем явно закодируйте остальную часть приложения.

У кого-нибудь есть идея получше?

Еще одно решение проблемы запуска приложения без пера.

Вместо выделения собственного контроллера просто используйте дополнительные параметры в методе NSApplicationMain () :

int retVal = NSApplicationMain(argc, argv, @"UIApplication", @"MyAppDelegate");

Это берет на себя все необходимые ссылки.

Тогда единственное, что вам нужно запомнить, - это сделать свое собственное окно и установить его видимым.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top