Передать managedObjectContext (данные ядра) другим классам, правильно ли сделано? - PullRequest
4 голосов
/ 17 января 2012

Я использовал шаблон по умолчанию, предоставленный Apple с Core Data (managedObjectContext находится в AppDelegate).Сначала я включал appdelegate.h во все классы, в которых мне нужно было использовать managedObjectContext, но я понял, что это неправильный способ сделать это.Apple говорит, что лучше передавать контекст только другим классам, которые в нем нуждаются, и так далее, поэтому я так и сделал.Дело в том, что это выглядит немного «хакерски», как я это сделал, и мне интересно, есть ли лучший вариант или мое решение верное.

Мое приложение в настоящее время настроено так (вот SSмоя раскадровка): enter image description here

Итак, мое корневое окно - это UITabBarController, а каждая вкладка - это UINavigationController, который указывает на несколько UITableViewController / UIViewController.

Вот то, что у меня есть в моем Appdelegate дляпередать экземпляр managedObjectContext на 2 вкладки:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    UITabBarController *rootViewController;
    UINavigationController *navigationController;
    ItemsTableViewController *itemsTableViewController;

    // Get the root window (UITabBarController)
    rootViewController = (UITabBarController *)self.window.rootViewController;


    // Get the second item of the UITabBarController
    navigationController = [[rootViewController viewControllers] objectAtIndex:1];

    // Get the first item of the UINavigationController (ItemsTableViewController)
    itemsTableViewController = [[navigationController viewControllers] objectAtIndex:0];
    itemsTableViewController.managedObjectContext = self.managedObjectContext;


    // Get the third item of the UITabBarController (again ItemsTableViewController)
    navigationController = [[rootViewController viewControllers] objectAtIndex:2];

    // Get the first item of the UINavigationController (ItemsTableViewController)
    itemsTableViewController = [[navigationController viewControllers] objectAtIndex:0];    
    itemsTableViewController.managedObjectContext = self.managedObjectContext;

    return YES;
}

Все работает хорошо, но необходимость многократного вызова objectAtIndex для перехода к нужному ViewController выглядит лучше ...

Любое лучшее решение?

Спасибо!

1 Ответ

10 голосов
/ 17 января 2012

Вы должны использовать метод prepareForSegue: для передачи вашего managedObjectContext другим контроллерам.

В качестве альтернативы вы можете создать подкласс контроллера панели вкладок и добавить контекст управляемого объекта в качестве свойства, к которому затем можно получить доступ из любого места в вашем приложении при условии, что контроллер панели вкладок также находится там.

Наконец, если вы когда-либо собираетесь использовать только один контекст (т.е. без многопоточности), вы всегда можете установить класс CoreDataHelper с методом класса, который возвращает ваш контекст по умолчанию всякий раз, когда вы запрашиваете его.Чтобы избежать импорта помощника в каждый отдельный класс, просто добавьте помощник в предварительно скомпилированный заголовочный файл (.pch) и разрешите ему также импортировать <CoreData/CoreData.h> framework.

Если вы хотите увидеть пример того, как это происходитготово, извлеките MagicalRecord на github https://github.com/magicalpanda/MagicalRecord

[EDIT] Вот пример того, как вы должны передать контекст, используя метод prepareForSegue.Помните, что этот метод вызывается, когда начинается инициация segue, и дает вам возможность настроить контроллер представления, который собирается выдвигать.Здесь вы можете передавать ссылки делегатов и присваивать значения другим переменным в контроллере представления назначения:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    NSString *segueIdentifier = [segue identifier];
    if ([segueIdentifier isEqualToString:@"YourSegueIdentifier"]) // This can be defined via Interface Builder
    {
        MyCustomViewController *vc = [segue destinationViewController];
        vc.managedObjectContext = self.managedObjectContext;
    }
}
...