iOS Core Data - 将上下文传递给详细视图的设计模式
Posted
技术标签:
【中文标题】iOS Core Data - 将上下文传递给详细视图的设计模式【英文标题】:iOS Core Data - Design Pattern for Passing Context to Detail Views 【发布时间】:2010-10-27 04:27:25 【问题描述】:我对一个我认为可以追溯到我的设计的问题感到有些困惑。
我正在基于一组主要静态的行 (4) 构建一个 TableViewController - 使用它作为 UITableView 的基础。每一行都会启动不同的视图(详细信息和 UITableViews)......在我的顶视图的托管对象上下文中,我可以轻松导航到关联的详细视图,因为它在上下文中(昵称).. 我最初只是想拥有不相关的表格和一系列会触发视图的按钮......但我放弃了这个想法。我当前的主要问题是知道如何切换 MOC 或不同的 fetchedresults 控制器(通过在每个 .m 中定义的方式从不同的表中获取。
目前,我在 TableViewControler.m 中有一个开关。这个片段有效:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
NSInteger switchval = indexPath.row;
switch (switchval)
case 0: // Nickname
//This version brings up a detailed view controller -
NickNameDetail *controller = [[NickNameDetail alloc] initWithNibName:@"NickNameDetail" bundle:nil];
controller.fetchedResultsController = self.fetchedResultsController;
controller.managedObjectContext = [self.fetchedResultsController objectAtIndexPath:indexPath];
[self.navigationController pushViewController:controller animated:YES];
break;
case 1:
//NextTableViewContoller *.... (etc)... here here
...
但是,我不知道如何切换到不同的上下文并获取不同的行。
meTableViewController.managedObjectContext = self.managedObjectContext;
nickNameDetail.managedObjectContext = self.managedObjectContext;
nextTableViewController.managedObjectContext = self.managedObjectContext;
以前有人遇到过这样的情况吗?抱歉,无法让代码格式化程序正常运行。
谢谢!
【问题讨论】:
【参考方案1】:在某些情况下,将当前视图控制器的 MOC 传递给推送到导航堆栈上的新视图控制器可能是好的/合适的。但是,您通常希望传递一个新创建的 MOC。请按如下方式执行:
在您的应用委托中添加以下方法
- (NSManagedObjectContext*)createNewManagedObjectContext
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
[moc setPersistentStoreCoordinator:[self persistentStoreCoordinator]];
return [moc autorelease];
在您的视图控制器中按如下方式传递 MOC
myAppDelegate *mainDelegate = (myAppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *mainMOC = [mainDelegate createNewManagedObjectContext];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:mainMOC];
newViewController.managedObjectContext = mainMOC;
然后根据需要处理通知,这里是一个例子
- (void)contextDidSave:(NSNotification *)notification
[managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
[self.tableView reloadData];
您还需要为每个视图控制器定义和使用不同的 NSFetchedResultsController。这是因为对于每个视图控制器(不同的实体、谓词等),您要获取和显示的数据当然是不同的。只需在每个实现文件中定义它们。这是一个例子:
- (NSFetchedResultsController *)fetchedResultsController
if (fetchedResultsController != nil)
return fetchedResultsController;
/*
Set up the fetched results controller.
*/
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Context" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
if(self.project)
// get the contexts for the project
NSPredicate * predicate = [NSPredicate predicateWithFormat: @"projectName == %@", self.project.name];
[request setPredicate:predicate];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES selector:@selector(caseInsensitiveCompare:)];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
[aFetchedResultsController release];
[request release];
[sortDescriptor release];
[sortDescriptors release];
return fetchedResultsController;
然后根据需要使用 fetchedResultsController。例如,把它放在你的 viewDidLoad
方法中:
NSError *error;
if (![[self fetchedResultsController] performFetch:&error])
// Handle error
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1); // Fail
【讨论】:
非常感谢!我会试试这个。它在各个层面上都有意义。对不起,我的回复晚了,我的偏好中的电子邮件通知似乎不起作用...... 好吧,如果您喜欢这个答案,请考虑投票;-) 您好,不可原谅,这种方法实际上效果很好。我只是将它连接起来,只收到 2 个警告:(1)“mainDelegate”的本地声明隐藏了实例变量(2)“myAppDelegate”可能不响应“-createNewManagedObjectContext”。我将深入研究该分析,但我必须说,我印象深刻! 我有兴趣了解与整个项目谓词相关的这篇文章。在此之前我没有任何谓词,但在我得到它之后毫无疑问。 if(self.project) // 获取项目的上下文 NSPredicate * predicate = [NSPredicate predicateWithFormat: @"projectName == %@", self.project.name]; [请求集合谓词:谓词]; .... 你肯定得到了我的回答!非常感谢您! :) 解决警告: 1) 将 mainDelegate 更改为不同的东西(例如 myDelegate),因为您已经有一个名为 mainDelegate 的变量; 2)在您的应用程序委托的头文件中添加方法 - (NSManagedObjectContext*)createNewManagedObjectContext;以上是关于iOS Core Data - 将上下文传递给详细视图的设计模式的主要内容,如果未能解决你的问题,请参考以下文章
如何将多个参数传递给 ASP.NET CORE MVC 中的 HttpGet 方法?