核心数据和 UITabBar 控制器 - 帮助?

Posted

技术标签:

【中文标题】核心数据和 UITabBar 控制器 - 帮助?【英文标题】:Core Data and UITabBar Controller - help? 【发布时间】: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 引用它。啊,这感觉真好:)

【问题讨论】:

【参考方案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。

【讨论】:

以上是关于核心数据和 UITabBar 控制器 - 帮助?的主要内容,如果未能解决你的问题,请参考以下文章

如何成就更高远控帧率和流畅度?向日葵SADDC算法浅析

如何成就更高远控帧率和流畅度?向日葵SADDC算法浅析

iOS - 核心数据 - 完成处理程序

IOS:UITabbar 项目单击一次又一次,它正在减少IOS 7 中的UITabbar 按钮项目大小

将对象从 Realm 数据库传输到另一个 UITabBar 控制器

关于edgesForExtendedLayouttranslucentextendedLayoutIncludesOpaqueBarsautomaticallyAdjustsScrollView(代码