Два экземпляра AppDelegate, как это исправить? - PullRequest
0 голосов
/ 26 декабря 2011

Я только что заметил довольно серьезную ошибку в своем приложении для 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 UIWindow и заметил, что это nil. Сначала я был в замешательстве, но потом понял, что сначала мой main метод создает экземпляр AppDelegate, который создает UIWindow и контроллеры представления в -application:didFinishLaunchingWithOptions:, а затем -sharedAppDelegate создает другой один ! Мне кажется очень странным, что мое приложение до сих пор работало достаточно хорошо, потому что, например, только первый экземпляр вызывает -saveContext, когда приложение существует.

В любом случае, я бы хотел изменить его, чтобы метод main также использовал sharedAppDelegate. Значит ли это, что мне нужно переопределить метод -init? Как я могу предотвратить бесконечный цикл (в конце концов -sharedAppDelegate также вызывает init)? Должен ли я сделать _sharedObject переменную глобальной области видимости?

1 Ответ

5 голосов
/ 26 декабря 2011

Вы не создаете свой собственный экземпляр делегата приложения.UIKit Framework создает один для вас, когда приложение запускается.Вы получаете текущий делегат приложения из метода delegate в UIApplication.Поэтому, когда вы хотите получить контекст общего управляемого объекта:

// 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];

Вы всегда можете получить текущее одноэлементное UIApplication с методом sharedApplication, и вы всегда можете получить правильный экземпляр вашего делегата приложения, используяdelegate метод в экземпляре приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...