Где установлен ваш делегат приложения и кто инициализирует его свойства window и viewController? - PullRequest
14 голосов
/ 24 сентября 2011

У меня очень новый вопрос о приложениях IOS ... Если я создаю новое приложение на основе представления с именем TestForStackOverflow, Xcode автоматически создает такой код для TestForStackOverflowAppDelegate.h:

@class TestForStackOverflowViewController;

@interface TestForStackOverflowAppDelegate : NSObject <UIApplicationDelegate>

@property (nonatomic, retain) IBOutlet UIWindow *window;

@property (nonatomic, retain) IBOutlet TestForStackOverflowViewController *viewController;

@end

и следующие в TestForStackOverflowAppDelegate.m:

#import "TestForStackOverflowAppDelegate.h"

#import "TestForStackOverflowViewController.h"

@implementation TestForStackOverflowAppDelegate

@synthesize window = _window;
@synthesize viewController = _viewController;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.

    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

[...]

А вот и мои вопросы:

1) где класс TestForStackOverflowAppDelegate установлен в качестве делегата для текущего приложения? Это сделано "автоматически"? Я видел, что исходный файл main.m содержит только следующий код:

int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];
    return retVal;
}

Не должен ли он установить класс делегата приложения в четвертом параметре вызова функции UIApplicationMain?

2) где устанавливаются свойства window и viewController класса TestForStackOverflowAppDelegate?

3) это может быть тривиально, но почему мы синтезируем window = _window, не имея переменной экземпляра с именем _window в интерфейсе TestForStackOverflowAppDelegate? Я видел, что вы можете объявить @properties, не имея соответствующих iVars в интерфейсах классов (возможно, они автоматически создаются компилятором), но является ли это хорошей практикой или вы всегда должны создавать соответствующие iVars в своих классах?

Извините за очень длинное сообщение, я просто надеюсь, что я не написал слишком очевидный вопрос, поскольку здесь, в Италии, поздно ночью, и я очень устал ... но когда эти вопросы приходят мне в голову, я могу ' t ждать решения:)

Ответы [ 2 ]

13 голосов
/ 24 сентября 2011

Как загружается класс делегата приложения?

В вашем файле -info.plist есть ключ с именем «Основное имя файла основного пера», который имеет вид, похожий на MainWindow.xib. В этом xib-файле есть прокси-объект владельца файла, и для него установлен делегат класса делегата приложения.

Откройте этот XIB в конструкторе. Обратите внимание на объект «Владелец файла» вверху, щелкните его контекстным контекстом и посмотрите на объект делегата. Теперь посмотрите на объекты в дизайне ниже линии (XCode 4) - вы должны увидеть там объект делегата приложения.

Где находится окно и viewController для набора appDelegate?

Посмотрите в конструкторе и щелкните контекстный объект объекта делегата под строкой (XCode 4). Там находится цель window и viewController.

_window iVar

Он автоматически предоставляется для вас. Мне не ясно, наследуется ли он или генерируется компилятором.

Подробнее об _ iVars: Зачем переименовывать синтезированные свойства в iOS с ведущими подчеркиваниями?

Если вы решили сделать эквивалент в коде:

удалить ссылку на ссылку main.m: пароль делегата

int main(int argc, char *argv[])
{
    int retVal = UIApplicationMain(argc, argv, nil, @"HelloViewAppDelegate");

В приложении делегат:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    CGRect screenBounds = [[UIScreen mainScreen] applicationFrame];
    CGRect windowBounds = screenBounds;
    windowBounds.origin.y = 0.0;

    // init window
    [self setWindow: [[UIWindow alloc] initWithFrame:screenBounds]];

    // init view controller
    _mainViewController = [[MainViewController alloc] init];

    [[self window] addSubview:[_mainViewController view]];

    [self.window makeKeyAndVisible];
    return YES;
}
3 голосов
/ 24 сентября 2011

1) Проще говоря, когда вызывается UIApplicationMain(),

  • Ваше приложение. Список найден,
  • поиск ключа "Основное имя файла основного пера",
  • этот XIB открыт,
  • Объект, поддерживающий протокол UIApplicationDelegate, создается и используется как делегат приложения

2) Они установлены в XIB, вы можете просмотреть их, если вы

  • открыть основной XIB,
  • выберите объект AppDelegate,
  • открыть инспектор соединений для этого объекта,
  • загляните в раздел Outlets

3) Вы правы, они создаются компилятором автоматически. Это делает код более читабельным благодаря меньшему количеству строк и упрощает рефакторинг, имея только одно место, в котором объявлено свойство.

Надеюсь, это поможет!

...