将ManagedObjectContext传递给第二个视图
我正在编写我的第一个iPhone/Cocoa应用程序。它在导航视图内有两个表格视图。当您触摸第一个表格视图中的一行时,您将转到第二个表格视图。我希望第二个视图显示与您在第一个视图中触摸的行相关的CoreData实体的记录。将ManagedObjectContext传递给第二个视图
我的CoreData数据在第一个表格视图中显示正常。您可以触摸一行并转到第二个表格视图。我能够将所选对象的信息从第一个视图传递到第二个视图。但我无法获得第二个视图来完成自己的CoreData抓取。对我来说,我无法让managedObjectContext对象传递给第二个视图控制器。我不想在第一个视图中执行查找并传递字典,因为我希望能够使用搜索字段来优化第二个视图中的结果,并从此处将新条目插入到CoreData数据中。
下面是从第一个视图切换到第二个视图的功能。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here -- for example, create and push another view controller.
NSManagedObject *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath];
SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:@"SecondView" bundle:nil];
secondViewController.tName = [[selectedObject valueForKey:@"name"] description];
secondViewController.managedObjectContext = [self managedObjectContext];
[self.navigationController pushViewController:secondViewController animated:YES];
[secondViewController release];
}
这里面SecondViewController的功能崩溃:
- (void)viewDidLoad {
[super viewDidLoad];
self.title = tName;
NSError *error;
if (![[self fetchedResultsController] performFetch:&error]) { // <-- crashes here
// Handle the error...
}
}
- (NSFetchedResultsController *)fetchedResultsController {
if (fetchedResultsController != nil) {
return fetchedResultsController;
}
/*
Set up the fetched results controller.
*/
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
// **** crashes on the next line because managedObjectContext == 0x0
NSEntityDescription *entity = [NSEntityDescription entityForName:@"SecondEntity" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
// <snip> ... more code here from Apple template, never gets executed because of the crashing
return fetchedResultsController;
}
任何的想法是什么,我做错了什么?
managedObjectContext是保留属性。
更新:我插入了NSLog([[managedObjectContext registeredObjects] description]);在viewDidLoad和它似乎managedObjectContext传递就好了。尽管如此,它仍在崩溃。
终止应用程序由于未捕获的异常“NSInternalInconsistencyException”,原因是:“+ entityForName:找不到的实体名称的NSManagedObjectModel“SecondEntity”
哦,这很有趣。我花了一些时间跟踪堆栈跟踪,我想我已经弄清楚了。
所以pushViewController调用viewDidLoad不是一次,而是两次。第一次调用viewDidLoad时,对象似乎不能正确实例化。第二次,他们是。因此,第一次运行代码时,它无法访问managedObjectContext,并引发异常。第二次运行,一切都很好。没有崩溃。
有很多关于viewDidLoad在Google上执行多次的问题的引用,所以我认为解决方案是不要在viewDidLoad中执行这个获取请求初始化。
你肯定有一个名为“SecondEntity”的实体? (这将是直接的解释错误信息的方法。)
但是,如果这是一个主列表 - >详细视图类型交互,我会建议将选定对象直接传递给第二个视图控制器,而不是给予它只是“tname”。这个对象可能包含你需要通过它的属性直接填充第二个表格的所有东西。
这样,您实际上并没有在第二个视图控制器中进行任何显式提取。即:
@interface SecondViewController : UITableViewController
@property (nonatomic, retain) NSManagedObject *selectedObject;
@end
@implementation SecondViewController
- (void)viewDidLoad
{
NSMutableArray *stuff = [[[selectedObject valueForKey:@"aToManyRelationship"] allObjects] mutableCopy];
// sort stuff the way you want to display them, etc.
}
...
是的,实体存在。 它不是主列表 - >细节..它更像是category-> items,我希望能够直接与数据存储进行交互,因为第二个视图实际上是主交互屏幕,所以我不想要只是将快照传递给第二个视图。 – amo 2009-07-02 15:40:51
只是踢..尝试更换:
NSEntityDescription *entity = [NSEntityDescription entityForName:@"SecondEntity" inManagedObjectContext:managedObjectContext];
有:
NSEntityDescription *entity = [NSEntityDescription entityForName:@"SecondEntity" inManagedObjectContext:[self managedObjectContext]];
你是通过设置器managedObjectContext,然后试图直接访问伊娃。根据您的属性的定义,这可能不正确。 [self managedObjectContext]将尝试通过getter访问该值,而不是直接访问该值。
有趣。当我回家时我会试试这个。 – amo 2009-07-02 15:41:42
我一直在努力解决同样的问题,我仍然只是一个新手。我想我知道发生了什么事情。让我知道这是否合理。
总之,你正试图从尚未设置的objectContext中获取实体。因此,您的选择是在此视图加载之前立即设置或在应用程序的其他位置进行设置。
如果您的应用程序就像是从与主UIApplicationDelegate还管理CoreData堆栈iPhone开发中心CoreDataBooks应用演示设置,那么你应该能够做到以下几点:
if (managedObjectContext == nil) { managedObjectContext = [[[UIApplication sharedApplication] delegate] managedObjectContext]; }
这应该做的伎俩。
有一点可以肯定,行: secondViewController.managedObjectContext = [self managedObjectContext];
应该是: secondViewController.managedObjectContext = self.managedObjectContext;
除非当前对象实现了一个名为'managedObjectContext'的方法,该方法返回该变量。
这可能是问题所在。
简短的回答:删除你的应用程序,然后再次运行它。
长回答:
如果你建立并运行项目,CoreData将节省你的模型,无论你到(持久存储位置)说。
如果您在CoreData模型中更改了某些内容,那么当您再次运行该应用程序时,新模型将不会与为您提供该错误的已保存模型相匹配。
要修复它,请删除您的应用程序。这将摆脱保存的模型,当你再次运行它时,它会重新创建你的新模型。
可以抑制“-managedObjectContext”没有协议的警告由第一投射您的应用程序委托发现:
if (managedObjectContext == nil) { managedObjectContext = [(MyAppDelegateName *)[[UIApplication sharedApplication] delegate] managedObjectContext]; }
我有这个问题,发现我的对象的初始化信息被访问managedObjectContext的setManagedObjectContext是前被称为...
前:
dataController = [[DataController alloc] init];
[dataController setManagedObjectContext:[self managedObjectContext]];
后:
dataController = [DataController alloc];
[dataController setManagedObjectContext:[self managedObjectContext]];
[dataController init];
feh。菜鸟错误。
Apple提供了一个名为“iPhoneCoreDataRecipes”的示例项目。有一个关于传递的NSManagedObjectContext here 如果试图实现这种逻辑,每个managedObjectContext是在每个UIViewController中
本身就是一个岛屿尝试改变代码
if (managedObjectContext == nil) { managedObjectContext = [(MyAppDelegateName *)[[UIApplication sharedApplication] delegate] managedObjectContext]; }
有了这个
很有趣的文章if (managedObjectContext == nil) { managedObjectContext = self.managedObjectContext }
tableViewController
,您可以通过managedObjectContext
由:secondTableController.managedObjectContext = [(AppDelegate *) [[UIApplication sharedApplication ] delegate ] managedObjectContext ]
,也许它的确定
将初始化抓取结果控制器的代码放入viewDidLoad时会发生什么?我有一个基本上同样的东西,它适用于我,但我创建我的fetched结果控制器直接在viewDidLoad与initWithFetchRequest:managedObjectContext:sectionNameKeyPath:cacheName :. – Tim 2009-07-02 14:08:24
@Tim我刚刚尝试过,它以相同的方式崩溃。奇怪的是,如果我设置了一个断点,self的所有成员变量都是NULL,但标题的设置是正确的,所以不能为true。 – amo 2009-07-02 14:24:31