簡體   English   中英

在哪里實施核心數據?

[英]where to implement Core Data?

我對核心數據編程完全陌生。 我只是想找出實現核心數據代碼的最佳位置。 我已經完成了蘋果教程 Locations 並且效果很好。 現在我嘗試將其轉移到我當前的項目中,這有點復雜。

Locations 教程展示了一個 RootViewController,包括一個以編程方式生成的 tableView。 我的項目基於 tabView 模板。 它擁有一個 MainWindow.xib,包括 TabBarController,其中包括三個 ViewController(MapView、ListView、SettingsView),其中每個視圖都有自己的 navigationController 和 xib 文件。

第一個絆腳石是更改它將使用 xib 為 tableView 運行的代碼,而不是以編程方式創建它。 我已經做到了,但仍然有一個錯誤。 我無法將 appDelegate 中的 managedObjectContext 連接到 listViewController。 我已經嘗試了這里論壇中針對該問題的示例和建議。 但它仍然不起作用。

在查看 CoreDataBooks 示例項目后,我發現核心數據代碼也在 RootViewController 中實現。 似乎在 ListViewController 中實現它是錯誤的方法。 但我的項目中沒有 RootViewController。 在 AppDelegate 中,我直接將 tabBarController 作為 rootViewController 傳遞。 因此我不知道如何訪問 listViewController 來設置上下文,就像在 Locations 示例中所做的那樣。

由於 MapView 是第一個視圖,我無法在 appDelegate 中設置上下文。 在使用 managedObjectContext 掙扎了很長時間之后,我想知道是否最好發明一個 RootViewController 以便能夠在那里放置額外的代碼。 model 應該可以被所有三個視圖訪問,並且似乎 RootViewController 是正確的位置。

但是我如何將它與包含另外三個基於 xib 文件的 viewControllers 的 tabBarController 結合起來呢? 有人可以推薦我示例或教程,包括基於標簽欄應用程序的核心數據嗎?

請閱讀 Marcus Zarra 的以下文章: 在 iOS 上傳遞 NSManagedObjectContext 這應該讓你知道如何解決你的問題。

通常,您應該向所有 ViewController 添加一個 NSManagedObjectContext 屬性,並在通過pushViewController:animated:將它們添加到視圖堆棧之前傳遞上下文。 您不應該從您的應用委托中獲取上下文。

如果將單個 NSManagedObject 傳遞給 ViewController,例如呈現一種詳細視圖,則可以從該 object 訪問上下文,因為每個 NSManagedObject 都知道它“生活”在其中的 NSManagedObjectContext。

如果您是注冊的 iOS 開發人員,我還推薦 WWDC 2010 和 2011 視頻。 有一些關於掌握核心數據的課程。

好的,現在我有正確的解決方案。 花了一些時間來理解,但現在它可以使用從應用程序委托到視圖控制器(listViewController)的依賴注入。

我的問題是我不知道如何引用我的視圖控制器,因為它們嵌套在專用的導航控制器和一個 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

列表視圖控制器.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;
    }

...

前段時間我編寫了一個類似的應用程序。 我解決它的方法是我制作了一個 singleton ,它有一個像 Apple 文檔中一樣的persistentStoreCoordinator屬性來保存對數據庫的訪問(所以我不必每次都寫它)。 然后在每個標簽欄視圖 controller 我已經啟動了它自己的 NSManagedObjectContext。

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

這樣,如果您理解我的意思,每個 controller 都會使用自己的上下文來處理數據庫。

請注意,如果您的任何視圖控制器具有詳細視圖 controller,請采用標准方法將托管 object 上下文傳遞給它,就像在示例代碼(書籍、位置、食譜)中一樣。

我剛剛修復了這個錯誤。 我錯過了 appDelegate 中一些必要的方法。 如果我將以下代碼放入 ListViewController 的 viewDidLoad 中,它現在可以工作

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;

如何在應用程序啟動后收集由 tabBarController 控制且不是 topView/superView 的其他 viewControllers 的引用? 第一個視圖是 MapView。 我必須在 appDelegate 中實例化或聲明 listViewController 嗎? 它必須如何編碼才能引用由 tabBarController 控制的 listViewController?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM