【问题标题】:Where is your Application Delegate set and who initializes its window and viewController properties?您的 Application Delegate 设置在哪里,谁初始化了它的 window 和 viewController 属性?
【发布时间】:2011-11-24 00:53:13
【问题描述】:

我有一个关于 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) TestForStackOverflowAppDelegate 类的 window 和 viewController 属性在哪里设置?

3) 这可能是微不足道的,但是为什么我们有合成窗口 = _window,而在 TestForStackOverflowAppDelegate 接口中没有一个名为 _window 的实例变量?我已经看到您可以声明 @properties 而无需在类接口中使用相应的 iVar(也许它们是由编译器自动创建的),但这是一种好习惯还是应该始终在您的类中创建相应的 iVar?

对不起,很长的信息,我只是希望我没有写一个太明显的问题,因为在意大利是深夜,我很累..但是当这些问题出现在我脑海中时,我可以'不要等待解决方案:)

【问题讨论】:

    标签: objective-c ios xcode uiapplicationdelegate


    【解决方案1】:

    应用委托类是如何加载的?

    在您的 -info.plist 文件中有一个名为“Main nib file base name”的键,并具有类似于 MainWindow.xib 的视图。在那个 xib 文件中,有一个文件的所有者代理对象,并且它有一个设置为应用程序委托类的委托。

    在设计器中打开那个 XIB。注意顶部的 File's Owner 对象,上下文单击它并查看委托对象。现在查看 (XCode 4) 行下方设计中的对象 - 您应该在那里看到应用程序委托对象。

    appDelegate 集的 window 和 viewController 在哪里?

    查看设计器并在上下文中单击 (XCode 4) 行下方的应用程序委托对象。 window 和 viewController 目标绑定在那里。

    _window iVar

    它会自动为您提供。我不清楚它是由编译器继承还是生成。

    这里有更多关于 _ iVar 的信息: Why rename synthesized properties in iOS with leading underscores?

    如果您选择在代码中执行等效操作:

    删除 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;
    }
    

    【讨论】:

    • Ok... 我检查了 MainWindow.xib 文件,在 plist 文件中被引用为 Main NIB 文件,我看到它定义了一些对象,例如 TestForStackOverflow App Delegate 和 TestForStackOverflow View Controller..我知道它们连接到相应的类,但这不能从检查器中看到:检查器引用 TestForStackOverflow App Delegate 而从不 TestForStackOverflowAppDelegate 类..我可以看到对“真实”的引用仅当我将 MainWindow.xib 文件作为 XML 文件打开时才可以类。顺便说一句,我已经了解魔术发生在哪里:)
    • 只是另一个疑问...当我创建一个基于 HelloWorld 视图的应用程序时,自动创建的 MainWindow.xib 文件仅用于指向您的 App Delegate 和 View Controller 类,对吗?它不用于绘制应用程序的界面,因为您有用于此目的的 HelloWorldViewController.xib 文件,还是我遗漏了什么?我知道这些可能是显而易见的问题,但我正在尝试将所有拼图拼凑在一起:)
    • 在 MainWindow.xib 中,应用程序委托的实例(行下方)具有 viewController 子类的视图控制器目标和已添加的 xib。所以在那种情况下,主窗口只是用于加载。可以添加从 UIViewController 继承的 MainWindow.m/h,它可能是目标 ViewController。但是...
    • 但是,我的 2 美分……最终界面构建器非常擅长布局。控制每个控件的各个方面最好在代码中进行控制,因为(1)我可以复制/粘贴我一直在做的块,而不是记住哪些框,我签入了 IB 和(2)它更容易合并。所以,我通过代码(上面)进行初始化,没有魔法或混乱。我仍然只使用 IB 进行布局。
    【解决方案2】:

    1) 简单来说,当UIApplicationMain()被调用时,

    • 找到你的应用程序.plist,
    • 查找“主 nib 文件基名称”键,
    • 此 XIB 已打开,
    • 支持UIApplicationDelegate 协议的对象被实例化并用作应用程序委托

    2)在XIB中设置,如果你可以查看它们

    • 打开主XIB,
    • 选择 AppDelegate 对象,
    • 为此对象打开连接检查器,
    • 查看奥特莱斯部分

    3) 你是对的,它们是由编译器自动创建的。它通过更少的行使代码更具可读性,并且更易于重构,仅在一个地方声明了属性。

    希望对你有帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多