Где установлен ваш делегат приложения и кто инициализирует его свойства window и viewController?
У меня вопрос о новинках о приложениях 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 ждать решения:)
Ответы
Ответ 1
Как загружается класс делегата приложения?
В вашем файле -info.plist есть ключ с именем "Основное имя файла основного файла" и имеет вид, похожий на MainWindow.xib. В этом xib файле есть прокси-объект владельца файла, и у него есть делегат, установленный в класс делегирования приложения.
Откройте этот XIB в дизайнере. Обратите внимание на объект File Owner наверху, щелкните его контекст и посмотрите на объект делегата. Теперь посмотрим на объекты в дизайне ниже строки (XCode 4) - вы должны увидеть объект делегирования приложения.
Где находится окно и viewController для набора appDelegate?
Посмотрите в дизайнере и контексте, нажмите на объект делегата приложения ниже строки (XCode 4). Объект window и viewController привязан там.
_window iVar
Он автоматически предоставляется для вас. Мне не ясно, унаследовано или сгенерировано компилятором.
Здесь больше на _ iVars:
Почему переименовать синтезированные свойства в iOS с лидирующими символами подчеркивания?
Если вы решили сделать эквивалент в коде:
удалить ссылку plist xib
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;
}
Ответ 2
1) Чтобы быть простым, когда вызывается UIApplicationMain()
,
- найдено ваше приложение .plist,
- отображается ключевое слово "Основное имя файла основного файла",
- этот XIB открывается,
- Объект, поддерживающий протокол
UIApplicationDelegate
, создается и используется как делегат приложения
2) Они установлены в XIB, вы можете просмотреть их, если вы
- откройте основной XIB,
- выберите объект AppDelegate,
- откройте инспектор подключений для этого объекта,
- загляните в раздел Outlets
3) Вы правы, они автоматически создаются компилятором. Это делает код более читаемым, имея меньше строк и более простой для рефакторинга, имеющий только одно место, объявленное им.
Надеюсь, что это поможет!