【问题标题】:Core Data and UITabBar Controller - help?核心数据和 UITabBar 控制器 - 帮助?
【发布时间】:2009-12-30 08:25:17
【问题描述】:

所以我有一个带有 UITabBarController 和一些导航控制器的项目,我正在尝试实现核心数据。它只是不工作。

我有一个奇怪的设置: UITabBarController -> 导航控制器 -> 表格视图控制器

我已经复制了所有核心数据代码并添加了一个具有属性的实体(“事件”和“名称” - 就像教程一样)。我不断收到错误: 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“+entityForName:找不到实体名称“事件”的 NSManagedObjectModel”

只有当我切换到我希望由 Core Data 内容填充的表视图时才会出现该错误。

在Table View Controller中发现错误出现在这一行:

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:managedObjectContext];

这似乎与此相对应(在 App Delegate 中):

NSManagedObjectContext *context = [self managedObjectContext];

if (!context) {

    // Handle the error.

NSLog(@"\nCould not create *context for self");

}

rootViewController.managedObjectContext = context;

有什么帮助吗?

更新:我设法让它发挥作用(非常激动人心的时刻,斯坦福在半场获胜 - 到目前为止,这是美好的一天)。我现在从 App Delegate 引用它。啊,这感觉真好:)

【问题讨论】:

    标签: iphone objective-c iphone-sdk-3.0 core-data uitabbarcontroller


    【解决方案1】:

    您的托管对象上下文可能未设置,并且实体“事件”显然对于 nil 上下文无效。

    我在所有视图控制器中都使用了对我的应用委托的引用,因此它们可以访问一个托管对象上下文。听起来其他人经常使用单例来管理 Core Data,并从中获取托管对象上下文。

    更新

    Where to place the “Core Data Stack” in a Cocoa/Cocoa Touch application 中有一个很好的讨论关于将核心数据堆栈保存在哪里。

    以下是一些将 Core Data 堆栈保留在应用委托中的示例代码:

    在 YourAppDelegate 中使用 Apple 的标准核心数据堆栈实现。 managedObjectContext 是作为示例实现的,但 managedObjectModel 和 persistentStoreCoordinator 也必须实现。

    YourAppDelegate.h

    @interface YourAppDelegate : NSObject <UIApplicationDelegate> {
        // Core Data stuff
        NSManagedObjectModel *managedObjectModel;
        NSManagedObjectContext *managedObjectContext;       
        NSPersistentStoreCoordinator *persistentStoreCoordinator;
    
        // other app ivars
    }
    

    YourAppDelegate.m

    - (NSManagedObjectContext *) managedObjectContext {
        if (managedObjectContext != nil) {
            return managedObjectContext;
        }
        NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
        if (coordinator != nil) {
            managedObjectContext = [[NSManagedObjectContext alloc] init];
            [managedObjectContext setPersistentStoreCoordinator: coordinator];
        }
        return managedObjectContext;
    }
    

    在每个视图控制器中,获取对应用委托的引用,并根据需要使用它来获取 managedObjectContext。比如设置fetchedResultsController的时候;

    RootViewController.h

    @interface RootViewController : UITableViewController <NSFetchedResultsControllerDelegate> {
        NSFetchedResultsController *fetchedResultsController;
    
        YourAppDelegate *app;
    }
    

    RootViewController.m

    #import "RootViewController.h"
    #import "YourAppDelegate.h"
    
    @implementation RootViewController
    
    @synthesize fetchedResultsController;
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        app = (YourAppDelegate*)[UIApplication sharedApplication].delegate;
    }
    
    - (NSFetchedResultsController *)fetchedResultsController {
        if (fetchedResultsController != nil) {
            return fetchedResultsController;
        }
    
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:app.managedObjectContext];
        [fetchRequest setEntity:entity];
    
        // setup the batch size, predicate, & sort keys, etc
    
        NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:app.managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"];
        aFetchedResultsController.delegate = self;
        self.fetchedResultsController = aFetchedResultsController;
    
        [aFetchedResultsController release];
        [fetchRequest release];
    
        return fetchedResultsController;
    }    
    

    【讨论】:

    • 你能给我举个例子吗?
    【解决方案2】:

    确保将 IB 中的 TableView (rootViewController) 连接到应用委托中的插座。

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题,我会分享我的解决方案。

      首先,您需要在 nib 文件的选项卡栏中引用导航控制器,确保将其连接起来。

      IBOutlet UINavigationController *navigationController;
      

      然后,按照支持文档中的建议获取 Controller 并将 managedObjectContext 发送给它:

      SavedTableViewController *saved = (SavedTableViewController *)[navigationController topViewController];
      saved.managedObjectContext = self.managedObjectContext;
      

      Alex(来自另一篇文章)是对的,“您通常应该远离从应用程序委托获取共享对象。这使得它的行为太像一个全局变量,并且与之相关的问题一团糟。 "

      【讨论】:

        【解决方案4】:

        我遇到了完全相同的问题,并在此处描述了如何解决它:

        iPhone: core data error: +entityForName: could not locate an NSManagedObjectModel for entity name 'Name'

        您需要将此行添加到您为标签栏创建视图控制器的应用委托中:

        yourViewController.managedObjectContext = self.managedObjectContext;
        

        【讨论】:

          【解决方案5】:

          引用 gerry3:

          听起来其他人经常使用单例来管理 Core Data,并从中获取托管对象上下文。

          对于任何试图通过使用单例实现它来解决这个问题的人,我开始了新问题here

          【讨论】:

            猜你喜欢
            • 2011-10-15
            • 2010-11-24
            • 2012-08-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多