为什么不强制在NIB中使用严格的单例应用程序委托对象?

时间:2014-04-04 19:57:13

标签: objective-c cocoa uiapplicationdelegate cocoa-design-patterns nsapplication-delegate

我只是围着圈子跑来跑去,所有这些都归结为在第二个NIB中实例化了一个不属于NSMainNibFile的app委托对象。令人惊讶的是如何让两名应用代表参与其中,这意味着您可以单独使用managedObjectContexts

这是一个想法 - 我可以让我的应用程序委托类成为单身人士吗?并在更多的XIB中安全地实例化它?会破坏什么?

此外,还有一些关于stackoverflow的提及[[UIApplication sharedApplication] delegate]是" singleton"但是UIApplicationDelegate协议并不保证超级类UIResponder也不是单例。那么我也可以在iOS上为自己拍脚吗?

[edit]看起来你可以在UIApplicationMain for iOS中找出delegateClassName并让主NIB加载委托对象,这样你就可以创建在OSX上看到的App Delegate对象模式,如果使用主NIB

[edit2] MainMenu.xib对于新的非文档应用程序的截图。使用此对象创建项目,使用window属性创建app delegate类。问题是在其他NIB中获取该方便的对象,该对象与[NSApp delegate]相同 enter image description here

3 个答案:

答案 0 :(得分:0)

好的,在问题被投票,然后由于谁知道为什么被投票归零,我继续调查我自己的答案。我认为让你的应用委派类真正的单身人士是有用的,这样你就不会引起NIB的麻烦。 我不明白为什么它会有害。我认为如果你的应用程序只有一个用户界面,那么让app委托拥有核心数据堆栈并不是不合理的。所有NIB。但是,推荐的设计模式是将每个窗口或视图控制器传递给ManagedObjectContext指针,并通过File的所有者占位符访问MOC,而不是使用App Delegate对象。

然而另一方面,"共享用户默认控制器" singleton,在每个NIB中获取一个特殊对象。我们不必向每个控制器传递一个指向它的指针,以便每个视图都可以访问它。它无所不在。应用代表是不同的。没有"共享应用代表"每个NIB中的对象。是的,有理由不与NIB中的应用代表交谈,但这不是问题的答案。

所以,答案。

单身人士设计模式: 很久以前由Apple在this deprecated reference document-- Creating a Singleton Instance.

中报道

原来我希望我的应用程序委托类实现的是" strict"实现,而不是具有可以创建app委托类的其他对象的工厂方法。这里的一个不同特征是让[NSApp delegate]成为主指针,而不是app委托类函数。

严格的实现必须覆盖我的应用程序委托类的allocWithZone(因为alloc调用allocWithZone)。

+ (MYAppDelegate*)allocWithZone:(NSZone *)zone
{
    if ([NSApp delegate] == nil) return [super allocWithZone:zone];
    return [NSApp delegate];
}

- (MYAppDelegate*)copyWithZone:(NSZone *)zone
{
    return self;
}

初始化只需返回[super init]即可,因此无需覆盖。

似乎工作。如果没有,我会更新。

[更新]我一直在调查使用NSBundle loadNibNamed:owner:topLevelObjects:的NIB加载 - 但似乎我得到一个带有新的app委托对象的数组,甚至从那种​​方法。该方法允许获取指向NIB中顶级对象的指针,而无需为其创建出口。似乎在MainMenu以外的XIB中获取app委托对象的最佳方法是使用类似上面的代码。

[另一个更新] 为什么它可能有害:根据" OS X中的顶级对象可能需要特殊处理"在this document中,我有充分的理由相信,即使使用ARC,我的这个答案也会增加[NSApp代表]的保留计数,但如果我觉得可以做桥梁和发布,那就太好了在dealloc中的app委托中,用于具有应用程序委托的顶级对象的窗口/视图控制器。另外,这意味着app委托类之外的代码。

答案 1 :(得分:0)

只需在现有的App Delegate中执行此操作(只有一个!)

// In the header file    
+ (AppDelegate*) sharedInstance;


// In the body
+ (AppDelegate*) sharedInstance {

    return (AppDelegate*) [[UIApplication sharedApplication] delegate];

}

然后,只要您想要引用App Delegate,就可以使用[AppDelegate sharedInstance],然后使用要调用的属性或实例方法。

答案 2 :(得分:0)

你不应该使用app delegate来处理核心数据。因此,将其作为强制执行的单身人士毫无意义。

理想情况下,根本不需要引用任何内容。