【问题标题】:Issues with UITableViewController with Segues, Core Data and Swift带有 Segues、Core Data 和 Swift 的 UITableViewController 的问题
【发布时间】: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。

【问题讨论】:

    标签: uitableview core-data swift xcode6 nsfetchedresultscontroller


    【解决方案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 必须更新表数据。这是一种合乎逻辑的行为。您必须检查代码崩溃的原因。
    • 虽然这不是答案,但它为我指明了正确的方向,可以在我的代码中找到一些逻辑错误。我的问题是我在输入数据之前向我的数据库中插入了一条新记录,因此我的数据总是为零。问题解决了。谢谢
    猜你喜欢
    • 2012-08-12
    • 1970-01-01
    • 1970-01-01
    • 2017-02-03
    • 2016-04-15
    • 2017-03-08
    • 2019-09-15
    • 2020-11-27
    • 1970-01-01
    相关资源
    最近更新 更多