为什么这个代码使用presentModalViewController? (不是pushViewController)

任何人都明白为什么在CoreDataBooks示例代码中:

(a)控制器交换差异的方法

虽然点击一个项目,并进入详细视图使用什么似乎是标准的“ pushViewController ”UINavigationController概念,当你点击“添加”一个新的loggingbutton时,它启动新的视图,通过“ presentModalViewController “方法? 也就是说,在两种情况下,都不能使用pushViewController方法吗?

每种方法在使用方法上有没有什么优势? 我看不清楚。 我猜想苹果公司一定会为不同的场景select不同的方法。 例如:

  1. 他们会看到的任何用户差异(即UI差异或function差异)?

  2. 开发商的任何差异(或优点/缺点)

例如,如果您要考虑使用pushViewController方法而不是用于“添加”scheme的presentModalViewController方法…

(二)数据共享方式差异

他们如何共享共同的数据对象的方法似乎是不同的 – 所以再次只是想知道为什么这些方法是不一样的? (即在这两种情况下,主控制器都暂时传递给另一个视图,并且它们之间有一些共享的数据 – 即子视图需要传递回父视图)

代码提取方便

这是“编辑”:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // Create and push a detail view controller. DetailViewController *detailViewController = [[DetailViewController alloc] initWithStyle:UITableViewStyleGrouped]; Book *selectedBook = (Book *)[[self fetchedResultsController] objectAtIndexPath:indexPath]; // Pass the selected book to the new view controller. detailViewController.book = selectedBook; [self.navigationController pushViewController:detailViewController animated:YES]; [detailViewController release]; } 

但是对于“添加”

 - (IBAction)addBook { AddViewController *addViewController = [[AddViewController alloc] initWithStyle:UITableViewStyleGrouped]; addViewController.delegate = self; // Create a new managed object context for the new book -- set its persistent store coordinator to the same as that from the fetched results controller's context. NSManagedObjectContext *addingContext = [[NSManagedObjectContext alloc] init]; self.addingManagedObjectContext = addingContext; [addingContext release]; [addingManagedObjectContext setPersistentStoreCoordinator:[[fetchedResultsController managedObjectContext] persistentStoreCoordinator]]; addViewController.book = (Book *)[NSEntityDescription insertNewObjectForEntityForName:@"Book" inManagedObjectContext:addingContext]; UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:addViewController]; [self.navigationController presentModalViewController:navController animated:YES]; [addViewController release]; [navController release]; } 

谢谢

您可以使用模态视图控制器将用户的注意力集中在任务上。 当你推动,用户在某种导航stream程,但仍然在他们的指尖总应用程序。 他们可能会决定前进还是后退,在中间切换到不同的标签。 当他们得到一个模态视图控制器,他们不能做任何事情,直到任务完成或取消(模态视图被驳回)

[警告:这个答案更适用于CoreDataBooks的更新代码,它更改为使用NSManagedObjectContext的new-in-iOS5 setParentContext方法,而不是与persistentStoreCoordinator混淆[

关于数据共享的第二个问题也通过模态添加与无模式编辑方法来解答。 在模拟器中运行应用程序,注意:

  1. 如果您点击添加您的下一个视图同时具有保存和取消button

  2. 如果你点击编辑你的下一个视图只有一个完成button。

(现在,在这个特定的项目中,您必须一次编辑每个字段,而字段编辑是在另一个视图中完成的,而且其中有一个“取消”button,但现在忽略,因为

一个。 这只适用于该领域。 例如,如果您编辑标题并点击保存,您将返回到编辑视图,并显示完成button,现在没有取消来撤销该更改,您只能点击完成。 就这个观点而言,你已经很less编辑书籍模式

湾 多么蹩脚的用户界面! 来吧苹果,使CoreDataBooks成为一个体面的,尽pipe简单的应用程序,遵循自己的约定。 至less把编辑放在单元格中。)

我们刚刚说到哪了? 哦,是的,“编辑” – 现有的Book是modeLESS,所以它在同一个MOC(NSManagedObjectContext)中传递原始Book,并且无法在编辑视图中取消对它的编辑。 另一方面,“添加”书是MODAL:它在详细视图中创build一个新的要编辑的书,并且如果用户点击取消则想要丢弃它。 为了达到这个目的,它必须使用第二个MOC,这是第一个孩子。 如果用户取消,则简单地忽略新的小孩MOC,有效地丢弃新的小册子; 如果用户保存,它将保存子MOC,将新的Book及其属性上移到父MOC中,然后保存父MOC。

这个孩子MOC的方法,顺便说一句,在WWDC 2011的演讲303“iOS上的核心数据有什么新东西”中有详细介绍。 在其他地方还有其他一些方法,其中包括

  • 使用零MOC创build新的托pipe对象,并且只有在用户点击保存时才将其插入到父MOC中

  • 不使用托pipe对象,而是使用不同的数据结构作为临时对象(我们不确定要保存的新书),比如NSDictionary,或者只是一组不同的variables

  • 和更多… ?

我喜欢亲子方法,因为苹果赞成它,因为它使用数据模型对象,而不是创build临时对象的并行数据结构。 无环境的方法也有这样的好处,还有(显然)更好的性能和简单性的附加好处(阅读我的嘴:没有新的MOCs)。 但我不相信没有托pipe对象上下文的托pipe对象是犹太教。

顺便说一句,CoreDataBooks并不完全遵循上述演示文稿中规定的约定,因为它不会将上下文保存在performBlock块中。

此外,我不知道为什么它将新的托pipe上下文设置为AddViewController属性,并没有使用它。