open iphone objective-c uiapplication

iphone - uiapplication openurl



¿Cuál es la relación entre AppDelegate, RootViewController y UIApplication? (5)

Cuando se inicia una aplicación Objective-C, comienza ejecutando la función denominada main (). No tiene que estar en el archivo "main.m" pero así es como el asistente de Xcode configura las cosas.

Dentro de la función main () producida por el asistente, hay esta línea:

int retVal = UIApplicationMain(argc, argv, nil, nil);

Eso es lo que inicia el marco "UIKit" que conforma toda la aplicación. Dentro de UIApplicationMain, se crea un objeto de tipo UIApplication. Y parte de lo que hace UIApplication cuando se inicia la aplicación es llamar al método applicationDidFinishLaunchingWithOptions en el miembro delegado de la clase UIApplication. Este delegado se configura en el archivo MainWindow.xib para que sea una instancia de su clase ProjectAppDelegate, una subclase de NSObject que se ajusta al protocolo UIApplicationDelegate.

Lo que hace que AppDelegate se ejecute inicialmente es ...

Debido a que en su archivo MainWindow.xib usted se ha conectado (bueno, el asistente del proyecto hizo la conexión en realidad) la salida "delegada" del Propietario del Archivo (que es el objeto UIApplication) al objeto UIApplicationDelegate en el archivo .xib, y la clase de UIApplicationDelegate se establece en la subclase UIApplicationDelegate de su aplicación.

Y no hay nada mágico en "MainWindow.xib", podría llamarse "Foo.xib", lo importante es que la propiedad en su archivo Info.plist llamada "Nombre de la base del archivo de la plumilla principal" es "MainWindow". Intente cambiar el nombre de MainWindow.xib a Foo.xib y cambiar el "Nombre de la base del archivo de la plumilla principal" en su Info.plist a "Foo" y verá que aún funciona.

EDIT: más sobre RootController

Una vez más, no hay nada mágico en el llamado "RootController". Este es solo el nombre de la subclase UIViewController creado para usted por el asistente para proyectos nuevos de Xcode.

El asistente coloca el código en el proyecto para dos clases: ProjectAppDelegate y ProjectViewController. La clase ProjectAppDelegate contiene dos miembros de salida:

IBOutlet UIWindow *window; IBOutlet ProjectViewController *viewController;

en el archivo MainWindow.xib, las instancias de UIWindow y ProjectViewController se colocan y se conectan a los puntos de venta anteriores en ProjectAppDelegate.

Lo que pone tus cosas en la pantalla es este código en tu clase 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; }

De nuevo, nada realmente mágico sobre esto: el asistente del proyecto creó un código que agrega la vista del "controlador de vista" raíz a la vista de la ventana y hace que la ventana esté visible. Su controlador de vista "raíz" se creó en el archivo .xib y se conectó a la salida ProjectAppDelegate.

Es muy instructivo tratar de crear una aplicación completamente por ti mismo sin utilizar ninguno de los archivos del asistente. Aprenderá mucho sobre cómo funcionan los archivos .xib y cómo se relacionan con los objetos de código.

Estoy tratando de averiguar la relación entre el appdelegate, RootViewControoler y UIApplication. Esto es lo que he descubierto hasta ahora:

Al iniciar su aplicación, se carga main.m.

Desde aquí, se carga su MainWindow.xib.

En su MainWindow.xib, el propietario de su archivo es de tipo UIApplication.

Establece el delegado de tu UIApplication en tu AppDelegate.

En el código fuente de su AppDelegate, puede configurar su RootViewController para que sea la primera vista que se muestra.

¿Es esto correcto? Lo que hace que AppDelegate se ejecute inicialmente

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

¿método?


Dado que su AppDelegate es un delegado de UIApplication, escucha todas las notificaciones que la clase de UIApplication publica durante su ciclo de vida. didFinishLaunching notificación de didFinishLaunching es una de ellas y hace que su AppDelegate llame al método mencionado anteriormente.


El punto de partida de las aplicaciones de iOS es siempre la función main() (gracias @bogatyr) que generalmente contiene código similar a,

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

Los dos últimos parámetros de UIApplicationMain son importantes y especifican el nombre de la clase principal y el delegado de la aplicación. Si son nil , se buscará Info.plist para la ventana principal xib (generalmente 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);

No es necesario configurar el propietario del archivo a través de xib, y se pueden especificar directamente en esta función UIApplicationMain .

principalClassName puede ser la cadena UIApplication o una subclase de UIApplication . De forma similar, delegateClassName se puede especificar directamente en este método. La clase delegada se crea una instancia utilizando init como dicen los documentos. Supongamos que especificamos nuestra clase delegada - MyAppDelegate como una cadena,

UIApplicationMain(int argc, char *argv[], nil, @"MyAppDelegate");

Primero se crea una instancia de UIApplication, que luego creará la clase delegada a partir de esta cadena usando NSClassFromString , supongo.

Una vez que se haya creado una instancia de delegateObject y la aplicación esté lista, se informará a este delegateObject mediante el método del delegado, 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:...];

Así es como UIApplication lo manejaría mediante programación, si no se usara una punta. Usar una punta en el medio no es muy diferente.


MainWindow.xib se define en su info.plist como el Main nib file base name . En su MainWindow.xib, usted define el primer controlador que desea cargar, en su caso, RootViewController .

didFinishLaunchingWithOptions: es parte del protocolo UIApplicationDelegate . Se sabe que este método (en iOS4.0 +) es el primero que se llama cuando se inicia una aplicación.


Para las aplicaciones Universal - iPhone + iPad - puede especificar que se carguen NIB diferentes en cada plataforma, ya sea en el panel de información de destino o agregando las NSMainNibFile~ipad y NSMainNibFile~iphone a su Info.plist . Alternativamente, puede agregar un NIB MainWindow~ipad.xib a su destino, se cargará en el iPad en lugar de MainWindow.xib , según la clave NSMainNibFile en Info.plist.

Si necesita más control y personalización para una aplicación Universal, puede cargar el NIB de inicio manualmente. La plantilla de proyecto "Universal" tiene la plantilla para este método, por lo que la forma más rápida de comenzar a usar esta técnica es crear un nuevo proyecto iOS con el perfil Universal.

En los ejemplos anteriores, el Main NIB File se configura en Info.plist (configuración de destino) para que ya tenga un NIB cargado cuando se invoque el delegado de su aplicación. Por lo general, en esta configuración, un objeto MyAppDelegate también se archivará en el NIB (con algunos IBOutlets ) y el File''s Owner del File''s Owner NIB se configurará en UIApplication .

Para que un proyecto universal pueda acomodar dos diseños alternativos, la clave del archivo NIB principal se queda fuera de Info.plist . Luego UIApplicationMain instancia del objeto delegado de la aplicación mediante programación en UIApplicationMain :

#import "MYAppDelegate.h" int main(int argc, char *argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([MYAppDelegate class])); } }

Luego verifique su entorno y configuración y cargue el NIB apropiado en la application:DidFinishLaunchingWithOptions:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { _window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; // Override point for customization after application launch. if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { _viewController = [[[MYViewController alloc] initWithNibName:@"MYViewController_iPhone" bundle:nil] autorelease]; } else { _viewController = [[[MYViewController alloc] initWithNibName:@"MYViewController_iPad" bundle:nil] autorelease]; } _window.rootViewController = _viewController; [_window makeKeyAndVisible]; return YES; } - (void)dealloc { [_window release]; [_viewController release]; [super dealloc]; }

El nuevo paso es crear un MYViewController raíz manualmente, cargando el NIB apropiado. En esta configuración, el File''s Owner es su nuevo MYViewController brillante en lugar de UIApplication . Si lo desea, MYViewController puede adoptar gran parte de lo que puede haber estado usando su delegado de aplicación, que a menudo es para encapsular la clase de modelo central de la aplicación, actuar como fuente de datos y delegar las vistas y otras cosas en el NIB.

Por lo tanto, se espera que tenga alguna UIView raíz en el NIB, y debe estar conectado a la salida del File''s Owner ( MYViewController ).

Tenga en cuenta que la NIB de MYViewController no se carga hasta la primera vez que se accede a la propiedad MYViewController.view . ¡Solo entonces se [MyViewController viewDidLoad] ! El momento más probable para que esto ocurra es cuando lo agrega a la ventana raíz.

En el código de plantilla que se muestra arriba, el UIWindow de la aplicación UIWindow una instancia de la raíz UIWindow , pero no hay razón para que no pueda incluirla en su NIB. Si decides hacer esto, ten cuidado. Si configura rootViewController de la ventana en el NIB al propietario del archivo en ese caso, causará que la vista del controlador se agregue a la ventana cuando se active la ventana. Tenga cuidado al construir ese primer NIB en cualquier caso.

El delegado de la aplicación no necesita necesariamente tener una referencia a su UIWindow la UIWindow raíz si desea que MYViewController lo administre, pero puede ser más limpio mantener la ventana raíz fuera de sus NIB y administrarla en el delegado de la aplicación.

Fuera de eso (!) No hay mucha diferencia con el enfoque de plataforma única.