AppDelegate的两个实例,如何解决?

时间:2011-12-26 10:01:02

标签: iphone objective-c core-data singleton

我刚注意到我的iPhone / iPad应用程序中存在一个相当严重的错误:我有一个名为AppDelegate的类,它实现了UIApplicationDelegate协议 - 就像每个iPhone应用程序一样。我正在使用Core Data,而AppDelegate设置我的托管对象上下文(我主要只是保留了Xcode模板的默认方法)。

现在我需要在我的应用中的几个地方使用托管对象上下文,我还想从几个地方调用-saveContext方法。所以我使用了单例模式并添加了一个类方法+ (AppDelegate *)sharedAppDelegate,它实现如下:

+ (AppDelegate *)sharedAppDelegate
{
    static dispatch_once_t pred = 0;
    __strong static id _sharedObject = nil;
    dispatch_once(&pred,^{
        _sharedObject = [[self alloc] init];
    });
    return _sharedObject;
}

到目前为止一切正常。但是,现在我尝试访问sharedAppDelegate的{​​{1}}属性,发现它是UIWindow。起初我很困惑,但后来我意识到我的nil方法首先创建了main的实例,它创建AppDelegate并在UIWindow中查看控制器然后, -application:didFinishLaunchingWithOptions:创建另一个!我发现很奇怪我的应用程序到目前为止似乎工作得很好,因为例如当应用程序存在时,只有第一个实例调用-sharedAppDelegate

无论如何,我想更改它,以便-saveContext方法也使用main。这是否意味着我需要覆盖sharedAppDelegate方法?如何防止无限循环(-init也会调用init)?我应该制作全局范围的-sharedAppDelegate变量吗?

1 个答案:

答案 0 :(得分:5)

您不会创建自己的应用委托实例。 UIKit Framework在应用程序启动时为您创建一个。您可以从UIApplication上的delegate方法获取当前的应用程序委托。因此,当您想要获取共享的托管对象上下文时:

// Get the instance of your delegate created by the framework when the app starts
AppDelegate* appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];

// Assuming you're using the default methods from the template...
NSManagedObjectContext* context = [appDelegate managedObjectContext];

您始终可以使用sharedApplication方法获取当前单例UIApplication,并且您始终可以使用应用程序实例上的delegate方法获取应用程序委托的正确实例。