где реализовать Core Data? - PullRequest
4 голосов
/ 11 июля 2011

Я совершенно новичок в программировании основных данных.я просто пытаюсь выяснить, где было бы лучшее место для реализации кода основных данных.я сделал Apple, учебник Locations, и он работал хорошо.Теперь я пытаюсь перенести это в мой текущий проект, который немного сложнее.

В руководстве Locations показан один RootViewController, включающий в себя программно сгенерированный tableView.мой проект основан на шаблоне tabView.он владеет файлом MainWindow.xib, включающим TabBarController, включая три ViewController (MapView, ListView, SettingsView), где у каждого представления есть свой навигационный контроллер и файл xib.

Первый камень преткновения изменял кодзапустите xib для tableView вместо того, чтобы создавать его программно.Я справился с этим, но есть еще одна ошибка.Я не могу подключить managedObjectContext из appDelegate к listViewController.Я попробовал примеры и предложения по этому вопросу на этом форуме здесь.но это все еще не работает.

После просмотра примера проекта CoreDataBooks я увидел, что код основных данных также реализован в RootViewController.Кажется, это было бы неправильным способом реализовать это в ListViewController.Но у меня нет RootViewController в моем проекте.В AppDelegate я напрямую передаю tabBarController как rootViewController.поэтому я не знаю, как добраться до listViewController, чтобы установить контекст, как это было сделано в примере Locations.

Поскольку MapView является первым представлением, я не могу установить контекст в appDelegate.И после долгой борьбы с managedObjectContext я думаю, что было бы лучше изобрести RootViewController, чтобы иметь возможность размещать там дополнительный код.модель должна быть доступна всем трем представлениям, и кажется, что RootViewController - правильное место.

Но как мне объединить это с tabBarController, который включает в себя еще три viewController на основе xib-файлов?Может ли кто-нибудь порекомендовать мне примеры или учебные материалы, включая основные данные, основанные на приложении панели вкладок?

Ответы [ 4 ]

3 голосов
/ 11 июля 2011

Пожалуйста, прочитайте следующую статью Маркуса Зарры: Передача NSManagedObjectContext на iOS . Это должно дать вам представление о том, как решить вашу проблему.

Как правило, вы должны добавить свойство NSManagedObjectContext ко всем вашим ViewControllers и передать контекст перед добавлением их в стек представления с помощью pushViewController:animated:. Вы не должны брать контекст у вашего делегата приложения.

Если вы передаете один NSManagedObject в ViewController, например, для представления своего рода подробного представления вы можете получить доступ к контексту из этого объекта, так как каждый NSManagedObject знает о NSManagedObjectContext, в котором он «живет».

Если вы являетесь зарегистрированным разработчиком iOS, я бы также порекомендовал видеоролики с WWDC 2010 и 2011. Есть несколько сессий по освоению основных данных.

1 голос
/ 13 июля 2011

хорошо, теперь у меня есть правильное решение. Понять это потребовалось некоторое время, но теперь он работает с внедрением зависимостей из делегата приложения в контроллеры представления (listViewController).

Моя проблема заключалась в том, что я не знал, как ссылаться на мои контроллеры представления, поскольку они вложены в выделенные контроллеры navController и один tabBarController.

после прочтения большого количества сообщений здесь я понял, что должен объявить свои контроллеры представления в appDelegate.h и синтезировать их в appDelegate.m, а затем соединить их с соответствующим элементом в IB. это было сделано быстро и легко после понимания: -)

Нет необходимости в rootViewController.

MyAppDelegate.h:

#import <UIKit/UIKit.h>
#import "ListViewController.h"

@interface MyAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {

    UIWindow *window;
    UITabBarController *tabBarController;
    IBOutlet ListViewController *listViewController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
@property (nonatomic, retain) IBOutlet ListViewController *listViewController;

@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;

- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;

@end

MyAppDelegate.m:

#import "MyAppDelegate.h"
#import "ListViewController.h"

@implementation MyAppDelegate

@synthesize window=_window;

@synthesize tabBarController=_tabBarController;

@synthesize managedObjectContext=__managedObjectContext;

@synthesize managedObjectModel=__managedObjectModel;

@synthesize persistentStoreCoordinator=__persistentStoreCoordinator;

@synthesize listViewController;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    NSManagedObjectContext *context = [self managedObjectContext];

    if (!context) {
        // Handle the error.
    }
    // Pass the managed object context to the view controller.
    listViewController.managedObjectContext = context;

    // Override point for customization after application launch.
    // Add the tab bar controller's current view as a subview of the window
    self.window.rootViewController = self.tabBarController;

    [self.window makeKeyAndVisible];
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque animated:NO];  
    return YES;
}

...

ListViewController.h

#import <CoreLocation/CoreLocation.h>


@interface ListViewController : UITableViewController <CLLocationManagerDelegate> {

    UINavigationController *navController;
    NSManagedObjectContext *managedObjectContext;
}

@property (nonatomic, retain) IBOutlet UINavigationController *navController;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;

-(NSManagedObjectContext *)managedObjectContext;

@end

ListViewController.m

#import "MyAppDelegate.h"
#import "ListViewController.h"


@implementation ListViewController

@synthesize navController;
@synthesize managedObjectContext;

- (void)viewDidLoad {

    [super viewDidLoad];

    NSLog(@"managedObjectContext: %@",[self managedObjectContext]);

    NSError *error = nil;
    if (![managedObjectContext save:&error]) {
        NSLog(@"error: %@",[self managedObjectContext]);
        return;
    }

...
0 голосов
/ 12 июля 2011

Я только что исправил ошибку.я пропустил некоторые методы, необходимые в appDelegate.это работает теперь, если я помещаю следующий код в viewDidLoad моего ListViewController

if (managedObjectContext == nil) { 
    NSLog(@"managedObjectContext is nil");
    managedObjectContext = [(IntraAppAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
}

Это нормально, относительно правильных правил шаблона MVC?в моем случае ViewController теперь берет контекст из appDelegate.

при попытке установить контекст в appDelegate что-то подобное выдает ошибку:

 NSManagedObjectContext *context = [self managedObjectContext];

    if (!context) {
        // Handle the error.
    }
    // Pass the managed object context to the view controller.

    self.tabBarController.listViewController.navController.managedObjectContext = context;
    self.window.rootViewController = self.tabBarController;

как я могу собрать ссылкудругих viewControllers, которые управляются tabBarController и не являются topView / superView после запуска приложения?Первый вид - это MapView.я должен создать экземпляр или объявить listViewController в appDelegate?как он должен быть закодирован, чтобы он ссылался на listViewController, управляемый tabBarController?

0 голосов
/ 11 июля 2011

Я закодировал такое приложение некоторое время назад.Я решил, что создал синглтон, у которого было свойство persistentStoreCoordinator, подобное тому, которое содержится в документации Apple, для хранения доступа к базе данных (поэтому мне не нужно писать его каждый раз).Затем в каждом контроллере панели вкладок я запускаю свой собственный NSManagedObjectContext.

NSPersistentStoreCoordinator *coordinator = [[Singleton sharedSingleton] persistentStoreCoordinator];
        if (coordinator != nil) {
            _managedObjectContext = [[NSManagedObjectContext alloc] init];
            [_managedObjectContext setPersistentStoreCoordinator: coordinator];
        }

Таким образом, каждый контроллер обращается к базе данных со своим собственным контекстом, если вы понимаете, о чем я.

Пожалуйстаобратите внимание, что если у любого из ваших контроллеров представления есть контроллер подробного представления, используйте стандартный подход для передачи ему контекста управляемого объекта, как в примере кода (Книги, Местоположения, Рецепты).

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