Iphone 在哪里实现核心数据?

Iphone 在哪里实现核心数据?,iphone,ios,core-data,nsmanagedobjectcontext,Iphone,Ios,Core Data,Nsmanagedobjectcontext,我对核心数据编程一无所知。我只是想找出实现核心数据代码的最佳位置。我已经完成了苹果教程,效果很好。现在我试着把这一点转移到我目前的项目中,这个项目有点复杂 “位置”教程显示了一个RootViewController,其中包含一个通过编程生成的tableView。我的项目基于选项卡式模板。它拥有一个MainWindow.xib,包括TabBarController,包括三个ViewController(MapView、ListView、SettingsView),其中每个视图都有自己的naviga

我对核心数据编程一无所知。我只是想找出实现核心数据代码的最佳位置。我已经完成了苹果教程,效果很好。现在我试着把这一点转移到我目前的项目中,这个项目有点复杂

“位置”教程显示了一个RootViewController,其中包含一个通过编程生成的tableView。我的项目基于选项卡式模板。它拥有一个MainWindow.xib,包括TabBarController,包括三个ViewController(MapView、ListView、SettingsView),其中每个视图都有自己的navigationController和xib文件

第一个绊脚石是更改代码,而不是通过编程方式创建代码,该代码将使用tableView的xib运行。我已经做到了,但仍然有一个错误。我无法将managedObjectContext从appDelegate连接到listViewController。我在这里尝试了这个论坛上关于这个问题的例子和建议。但它仍然不起作用

在查看CoreDataBooks示例项目后,我发现核心数据代码也在RootViewController中实现。在ListViewController中实现它似乎是错误的。但是我的项目中没有RootViewController。在AppDelegate中,我直接将tabBarController作为rootViewController传递。因此,我不知道如何访问listViewController来设置上下文,就像在Locations示例中那样

由于MapView是第一个视图,我无法在appDelegate中设置上下文。在与managedObjectContext斗争了很长一段时间之后,我想知道发明一个RootViewController以便能够在那里放置额外的代码是否更好。所有三个视图都应该可以访问模型,而且RootViewController似乎是正确的位置


但我如何将其与包含三个以上基于xib文件的ViewController的tabBarController结合起来呢?有人能推荐我一些例子或教程,包括基于选项卡栏应用程序的核心数据吗?

请阅读Marcus Zarra的以下文章:。这会让你知道如何解决你的问题

通常,您应该向所有ViewController添加NSManagedObjectContext属性,并在通过
pushViewController:animated:
将其添加到视图堆栈之前传递上下文。您不应该从应用程序代理获取上下文

如果将单个NSManagedObject传递给ViewController,例如,为了显示一种详细视图,可以从该对象访问上下文,因为每个NSManagedObject都知道它“生活”在其中的NSManagedObject上下文


如果你是一名注册的iOS开发者,我还推荐WWDC 2010和2011视频。有一些关于掌握核心数据的课程。

我不久前编写了一个类似的应用程序。我解决这个问题的方法是,我制作了一个singleton,它有一个
persistentStoreCoordinator
属性,就像Apple文档中的属性一样,用来保存对数据库的访问权限(所以我不必每次都写它)。然后在每个选项卡栏视图控制器中,我都启动了自己的NSManagedObjectContext

NSPersistentStoreCoordinator *coordinator = [[Singleton sharedSingleton] persistentStoreCoordinator];
        if (coordinator != nil) {
            _managedObjectContext = [[NSManagedObjectContext alloc] init];
            [_managedObjectContext setPersistentStoreCoordinator: coordinator];
        }
如果您理解我的意思,那么每个控制器都会使用自己的上下文来访问数据库


请注意,如果您的任何视图控制器都有详细视图控制器,请采用标准方法将托管对象上下文传递给它,就像在示例代码(书籍、位置、食谱)中一样。

我刚刚修复了该错误。我在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的其他ViewController的引用?第一个视图是MapView。我必须在appDelegate中实例化或声明listViewController吗?它引用由tabBarController控制的listViewController时必须如何编码?

好的,现在我有了正确的解决方案。理解它花了一段时间,但现在它可以使用从应用程序委托到视图控制器(listViewController)的依赖项注入

我的问题是,我不知道如何引用视图控制器,因为它们嵌套在专用的NavController和一个tabBarController中

在阅读了这里的大量帖子后,我明白了我必须在appDelegate.h中声明我的视图控制器,并在appDelegate.m中合成它们,然后将它们连接到IB中的appropirate项。理解之后,这项工作可以快速轻松地完成:-)

不需要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
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

谢谢你的回复。我已经读过这篇文章了。正如作者提到的,他还没有用IB做过,没有太多的信息。我尝试了->self.tabBarController.listViewController.navController.managedObjectContext=context;->但这不起作用。我目前正在开发的应用程序使用基于tabBarController架构的核心数据,因此我觉得我可能能够提供一些建议。你到底想做什么?将您的上下文传递到不同的选项卡?完全正确。我刚修复了我的错误。我能够从ListViewController中viewDidLoad内部的appDelegate获取上下文。不幸的是,我不允许在这里发布代码,因为我有超过100篇文章。但是明天我会发布更改。无论如何,我不确定这是否是通常的方式,我不完全确定是否有通常的方式。我个人的做法是用核心数据创建一个基于窗口的应用程序。然后在app委托中,我为我的tabBarController和它的选项卡视图创建了IBOutlets,然后合成了t
#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
#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;
    }

...