带有 Segues、Core Data 和 Swift 的 UITableViewController 的问题
Posted
技术标签:
【中文标题】带有 Segues、Core Data 和 Swift 的 UITableViewController 的问题【英文标题】:Issues with UITableViewController with Segues, Core Data and Swift 【发布时间】:2014-10-06 11:48:58 【问题描述】:Xcode 6.0.1,Swift ios 8
我有一个我认为非常简单的设置,但我遗漏了一些导致问题的东西,或者是默认行为。
我有以下:
Tab Bar Controller -> Navigation Controller -> Table View Controller -Seque-> Table View Controller
我将 UIBarButtonItem“添加”按钮 (addPlayerInformationDetail) 连接到第二个表视图控制器。问题是当我通过 segue 推送控制器时,代码在错误的表视图控制器上运行,并且它崩溃了。我理解它为什么会崩溃,但我不明白它为什么在第一个视图控制器上做某事。第一个表视图控制器也是 NSFetchedResultsControllerDelegate。
第一个 Table View Controller (PlayerInformationTableViewController) 使用标准的 Table View Controller 锅炉代码。这是 Segue 调用的
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
if debug==1
println("Running: ", reflect(self).summary.pathExtension,__FUNCTION__)
if segue.identifier == "addPlayerInformationDetail"
//Nothing to do at the moment
else if segue.identifier == "editPlayerInformationDetail"
var indexPath:NSIndexPath = tableView.indexPathForSelectedRow()!
var vc = segue.destinationViewController as PlayerInformationDetailTableViewController
vc.managedObjectID = self.fetchedResultsController.objectAtIndexPath(indexPath).objectID
这是所有方法的踪迹,我指出了代码返回到第一个表视图控制器的位置:
(Running: , AppDelegate, managedObjectContext)
(Running: , AppDelegate, persistentStoreCoordinator)
(Running: , AppDelegate, managedObjectModel)
(Running: , AppDelegate, applicationDocumentsDirectory)
(Running: , AppDelegate, application(_:didFinishLaunchingWithOptions:))
(Running: , PlayerInformationTableViewController, viewDidLoad())
(Running: , PlayerInformationTableViewController, viewWillAppear)
(Running: , PlayerInformationTableViewController, numberOfSectionsInTableView)
(Running: , PlayerInformationTableViewController, fetchedResultsController)
(Running: , PlayerInformationTableViewController, tableView(_:numberOfRowsInSection:))
(Running: , PlayerInformationTableViewController, fetchedResultsController)
(Running: , PlayerInformationTableViewController, numberOfSectionsInTableView)
(Running: , PlayerInformationTableViewController, fetchedResultsController)
(Running: , PlayerInformationTableViewController, tableView(_:numberOfRowsInSection:))
(Running: , PlayerInformationTableViewController, fetchedResultsController)
(Running: , AppDelegate, applicationDidBecomeActive)
(Running: , PlayerInformationTableViewController, prepareForSegue(_:sender:))
(Running: , PlayerInformationDetailTableViewController, putABorderAroundButtons())
(Running: , PlayerInformationDetailTableViewController, viewWillAppear)
(Running: , PlayerInformationDetailTableViewController, refreshInterface())
newPlayer (Function)
(Running: , PlayerInformationDetailTableViewController, newPlayer())
(Ending: , PlayerInformationDetailTableViewController, newPlayer())
Why is it going back to PlayerInformationTableViewController???
(Running: , PlayerInformationTableViewController, numberOfSectionsInTableView)
(Running: , PlayerInformationTableViewController, fetchedResultsController)
(Running: , PlayerInformationTableViewController, tableView(_:numberOfRowsInSection:))
(Running: , PlayerInformationTableViewController, fetchedResultsController)
(Running: , PlayerInformationDetailTableViewController, numberOfSectionsInTableView)
(Running: , PlayerInformationDetailTableViewController, tableView(_:numberOfRowsInSection:))
(Running: , PlayerInformationDetailTableViewController, tableView(_:numberOfRowsInSection:))
(Running: , PlayerInformationDetailTableViewController, tableView(_:numberOfRowsInSection:))
(Running: , PlayerInformationDetailTableViewController, tableView(_:numberOfRowsInSection:))
(Running: , PlayerInformationDetailTableViewController, numberOfSectionsInTableView)
(Running: , PlayerInformationDetailTableViewController, tableView(_:numberOfRowsInSection:))
(Running: , PlayerInformationDetailTableViewController, tableView(_:numberOfRowsInSection:))
(Running: , PlayerInformationDetailTableViewController, tableView(_:numberOfRowsInSection:))
(Running: , PlayerInformationDetailTableViewController, tableView(_:numberOfRowsInSection:))
(Running: , PlayerInformationTableViewController, tableView(_:cellForRowAtIndexPath:))
(Running: , PlayerInformationTableViewController, tableView(_:canEditRowAtIndexPath:))
(Running: , PlayerInformationTableViewController, configureCell(_:atIndexPath:))
(Running: , PlayerInformationTableViewController, fetchedResultsController)
点击 Add 按钮后 (Ending: , PlayerInformationDetailTableViewController, newPlayer()) 完成后为什么 PlayerInformationTableViewController 中的代码在运行?我在 Core Data 中添加了一行,但它不应该与 PlayerInformationTableViewController 中的 NSFetchedResultsControllerDelegate 有任何关系。
这是PlayerInformationDetailTableViewController中的代码流程
覆盖 func viewWillAppear(animated: Bool)
if debug==1
println("Running: ", reflect(self).summary.pathExtension,__FUNCTION__)
refreshInterface()
func refreshInterface()
if debug==1
println("Running: ", reflect(self).summary.pathExtension,__FUNCTION__)
if managedObjectID != nil
println("existingPlayer \(existingPlayer)")
existingPlayer()
else
println("newPlayer \(newPlayer)")
newPlayer()
func newPlayer()
if debug==1
println("Running: ", reflect(self).summary.pathExtension,__FUNCTION__)
//insert a new object in Core Data
var newPlayerInformation = NSEntityDescription.insertNewObjectForEntityForName("PlayerInformation", inManagedObjectContext: managedObjectContext!) as PlayerInformation
var newFirstName = playerInformationFirstNameTextField.text
var newLastName = playerInformationLastNameTextField.text
var newBirthPlace = playerInformationBirthPlaceTextField.text
newPlayerInformation.firstName = playerInformationFirstNameTextField.text
newPlayerInformation.lastName = playerInformationLastNameTextField.text
newPlayerInformation.birthPlace = playerInformationBirthPlaceTextField.text
if debug==1
println("Ending: ", reflect(self).summary.pathExtension,__FUNCTION__)
我希望我能正确解释这一点,因为这真的很令人沮丧,而且我确信这是我错过的一些简单的事情。如果我在 func refreshInterface() 中注释掉 //newPlayer(),则代码永远不会返回到 PlayerInformationTableViewController。提前致谢。 -PaulS。
【问题讨论】:
【参考方案1】:跟踪日志显示您的 NSFetchedResultsController 正在检测其 managedObjectContext 中的更改,因为添加了一条新记录。立即更新相关信息numberOfRowsInSection
...
根据NSFetchedResultsController Class Reference:
此外,获取的结果控制器还提供以下功能:
Optionally monitor changes to objects in the associated managed object context, and report changes in the results set to its delegate (see The Controller’s Delegate).
要禁用此跟踪,NSFetchedResultsController
的委托应设置为 nil
【讨论】:
我应该在何时/何处将NSFetchedResultsController
的委托设置为nil
,在我的segue 中?
NSFetchedResultsController
通知您的PlayerInformationTableViewController
必须更新表数据。这是一种合乎逻辑的行为。您必须检查代码崩溃的原因。
虽然这不是答案,但它为我指明了正确的方向,可以在我的代码中找到一些逻辑错误。我的问题是我在输入数据之前向我的数据库中插入了一条新记录,因此我的数据总是为零。问题解决了。谢谢以上是关于带有 Segues、Core Data 和 Swift 的 UITableViewController 的问题的主要内容,如果未能解决你的问题,请参考以下文章
带有 Core Data 和 Restkit 的多个视图控制器
如何使用带有 Swift 的 Core Data 获取非标准(可转换)属性来更新/保存和持久化?