AppDelegate,RootViewController和UIApplication之间有什么关系?

guy*_*214 25 iphone objective-c uiapplication

我试图弄清楚appdelegate,RootViewControoler和UIApplication之间的关系.这是我到目前为止所得到的:

启动应用程序时,main.m将被加载.

从这里,您的MainWindow.xib被加载.

在MainWindow.xib中,文件所有者的类型为UIApplication.

您将UIApplication的委托设置为AppDelegate.

在AppDelegate的源代码中,您可以将RootViewController设置为显示的第一个视图.

这是正确的吗?是什么促使AppDelegate最初运行它

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { }
Run Code Online (Sandbox Code Playgroud)

方法?

Bog*_*tyr 44

当Objective-C应用程序启动时,它首先运行名为main()的函数.它不必在文件"main.m"中,但这就是Xcode向导设置的方式.

在向导生成的main()函数中,有这一行:

int retVal = UIApplicationMain(argc, argv, nil, nil);
Run Code Online (Sandbox Code Playgroud)

这就是启动构成整个应用程序的"UIKit"框架的原因.在UIApplicationMain中,创建了UIApplication类型的对象.应用程序启动时UIApplication所做的部分工作是调用UIApplication类的委托成员上的applicationDidFinishLaunchingWithOptions方法.此委托在MainWindow.xib文件中设置为ProjectAppDelegate类的实例,该类是NSObject的子类,符合UIApplicationDelegate协议.

是什么促使AppDelegate最初运行它...

因为在您的MainWindow.xib文件中已经连接(实际上项目向导已经连接)文件的所有者(这是UIApplication对象)的"委托"出口到.xib文件中的UIApplicationDelegate对象,以及类将UIApplicationDelegate设置为您的应用程序的UIApplicationDelegate子类.

并且"MainWindow.xib"没有任何魔力,它可以被称为"Foo.xib",重要的是Info.plist文件中名为"主nib文件基本名称"的属性是"MainWindow".尝试将MainWindow.xib重命名为Foo.xib并将Info.plist中的"主nib文件基本名称"更改为"Foo",您将看到它仍然有效.

编辑:更多关于RootController

同样,所谓的"RootController"并没有什么神奇之处.这只是Xcode新项目向导为您创建的UIViewController子类的名称.

该向导将代码放在项目中,用于两个类:ProjectAppDelegate和ProjectViewController.ProjectAppDelegate类包含两个出口成员:

IBOutlet UIWindow *window;
IBOutlet ProjectViewController *viewController;
Run Code Online (Sandbox Code Playgroud)

在MainWindow.xib文件中,放置UIWindow和ProjectViewController的实例,并连接到ProjectAppDelegate中的上述插座.

ProjectAppDelegate类中的代码是在屏幕上显示的内容:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after application launch.

    // Add the view controller's view to the window and display.
    [self.window addSubview:viewController.view];
    [self.window makeKeyAndVisible];

    return YES;
}
Run Code Online (Sandbox Code Playgroud)

同样,没有什么真正神奇的:项目向导创建的代码将"根"ViewController的视图添加到窗口的视图中,并使窗口可见.您的"根"视图控制器是在.xib文件中创建的,并连接到ProjectAppDelegate插座.

尝试完全自己创建应用程序而不使用向导中的任何文件是非常有益的.您将学习很多关于.xib文件如何工作以及它们与代码对象的关系的知识.


Anu*_*rag 15

iOS应用程序的起点始终是main()函数(感谢@bogatyr),它通常包含类似于的代码,

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

最后两个参数UIApplicationMain很重要,并指定主类名和应用程序委托.如果是nil,则将查找Info.plist主窗口xib(通常MainWindow.xib).

// If nil is specified for principalClassName, the value for NSPrincipalClass
// from the Info.plist is used. If there is no NSPrincipalClass key specified, the
// UIApplication class is used. The delegate class will be instantiated 
// using init.
.. UIApplicationMain(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName);
Run Code Online (Sandbox Code Playgroud)

没有必要通过xib设置文件所有者,可以直接在此UIApplicationMain功能中指定它们.

principalClassName可以是字符串UIApplication或子类UIApplication.同样delegateClassName可以在此方法中直接指定.委托类使用init文档说明进行实例化.假设我们指定了我们的委托类 - MyAppDelegate作为字符串,

UIApplicationMain(int argc, char *argv[], nil, @"MyAppDelegate");
Run Code Online (Sandbox Code Playgroud)

首先实例化UIApplication的一个实例,然后使用NSClassFromString我的假设从该字符串创建委托类.

一旦实例化了delegateObject,并且应用程序就绪,将使用委托方法通知此delegateObject didFinishLaunchingWithOptions.

Class delegateClass = NSClassFromString(@"MyAppDelegate");
id <UIApplicationDelegate> delegateObject = [[delegateClass alloc] init];

// load whatever else is needed, then launch the app
// once everything is done, call the delegate object to
// notify app is launched
[delegateObject application:self didFinishLaunchingWithOptions:...];
Run Code Online (Sandbox Code Playgroud)

如果没有使用nib,这就是UIApplication如何以编程方式处理它.在中间使用笔尖没有太大的不同.