ios - CollectionView失去对数据模型的引用

标签 ios swift collectionview

有点困在同一个问题上好几天了。
我有一个ViewControllerA类,它充当CollectionView委托和数据源。CollectionView通过故事板连接。ViewControllerA类包含提供CollectionView的数据模型。
每当ViewControllerA第一次加载时,它会连接到数据库,并根据需要将信息加载到数据模型(userDictionary)中。一旦控制器加载了所有数据,它就会重新加载CollectionView,并触发同步方法来侦听数据库中的任何更改,从而相应地更新用户字典,并在CollectionView中重新加载相应的项。
到目前为止一切正常。
当我转换到任何不同的ViewController类(比如ViewControllerB类)时,我在prepareForSenderA中将用户字典的副本从ViewController a传递到ViewControllerB,并通过prepareForSenderB将其传递回ViewControllerA。
这是奇怪的行为。当我转换回ViewControllerA类时,CollectionView将使用传递给ViewControllerB的相同数据加载fine,但无法加载同步方法在ViewControllerA中观察到的任何新更改。
我知道同步方法仍然可以正常工作,因为当我在ViewControllerA中加载新数据时,它会在调试器中显示出来。我知道同一个控制器类中的userDictionary数据模型正在接收这些更新,因为一个didSet观察者正在打印userDictionary的最新状态。
奇怪的是,每当我在VisualSo操纵类中打印出数据模型的内容时,它就会打印出它在传递给VIEWSCONDERB类时存在的旧状态。即使didSet观察者刚刚证明了模型实际上是更新的!
就好像ViewControllerA类在某种程度上保留了对数据模型的引用,当它被传递给ViewControllerB时,当“模型”被传递时,不知何故“丢失”它对“自我”中的数据模型的引用。
另一个注意事项:如果我一直呆在ViewControllerA中,并且不来回传递userDictionary,我就不会再遇到这个问题。
下面的代码总结了我如何来回传递数据:
视图控制器A类:

class ViewControllerA: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

//MARK: Data Structures
var userDictionary = [[String: String]]() { didSet { print("userDictionary.count from DIDSET,", userDictionary.count)}}
//prints out: 9

//MARK: Initialization
override func viewDidLoad() {
    self.loadUserDictionaryFromDatabase()
}

func loadUserDictionaryFromDatabase() {
    //code that loads information from a database
    //var objectInstance["name"] = firstName
    //self.userDictionary.append(objectInstance)
    print("loader observed numberOfItems", numberOfItems)
    //...once data is fully loaded
    self.syncDataFromDatabase()
}

func syncDataFromDatabase() {
    //sync new data from database
    //var newObjectInstance["newName"] = newFirstName
    //self.userDictionary.append(newName)
    print("syncer observed newNumberOfItems", newNumberOfItems)
}

//MARK: View Controller Transitions
@IBAction func segueAtoB(_ sender: Any) {
    self.performSegue(withIdentifier: "segueAtoB", sender: self)
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    //Segue from VCA to VCB
    if segue.identifier == "segueAtoB" {

        let controller = segue.destination as! ViewControllerA

        //Pass initialized userDictionary from VCA to VCB
        controller.userDictionary = self.userDictionary
    }
}

//MARK: Dummy Test Number of Items in UserDictionary
@IBAction func printMostUpToDateNumberofItemsInDictionary(_ sender: Any) {
    print("userDictionary.count from TEST,", userDictionary.count)
}

}
视图控制器B类:
类ViewControllerB:UIViewController{
//MARK: Data Structures
var userDictionary = [[String: String]]()

//MARK: View Controller Transitions
@IBAction func segueBtoA(_ sender: Any) {
    self.performSegue(withIdentifier: "segueBtoA", sender: self)
}


override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    //1. Segue to Home-Screen Controller
    if segue.identifier == "segueBtoA" {

        let controller = segue.destination as! ViewControllerB
        controller.userDictionary = self.userDictionary
    }
}

}
打印结果:
步骤1:在视图控制器A中启动
装载机观察到的项目数=9
来自DIDSET的userDictionary.count,9
同步器观察到newNumberOfItems=1
DIDSET=10的userDictionary.count(10=9+1)--通过
TEST=10的userDictionary.count(10=9+1)--通过
第二步:从A到B
viewControllerB.userDictArray=viewControllerA.userDictArray
第三步:从B到A
viewControllerA.userDictArray=viewControllerB.userDictArray
步骤4:观察调试器输出
来自DIDSET的userDictionary.count,10
同步器观察到newNumberOfItems=1
DIDSET=11的userDictionary.count(10=10+1)--通过
TEST中的userDictionary.count=10(10!=10+1--失败
(当diSet刚刚更新了userDictionary.count时,这一行是如何发生的?)
使用UUID的调试器输出:
步骤1:在视图控制器A中启动
装载机观察项目数量,A74593E1-1231-41BE-A5DF-693591F998E4
来自DIDSET的userDictionary.count,A74593E1-1231-41BE-A5DF-693591F998E4
同步器观察到新的项目数量,A74593E1-1231-41BE-A5DF-693591F998E4
来自DIDSET的userDictionary.count,A74593E1-1231-41BE-A5DF-693591F998E4
来自测试的userDictionary.count,A74593E1-1231-41BE-A5DF-693591F998E4
步骤4:观察调试器输出
来自DIDSET的userDictionary.count,A74593E1-1231-41BE-A5DF-693591F998E4
同步器观察到新的项目数量,A74593E1-1231-41BE-A5DF-693591F998E4
来自DIDSET的userDictionary.count,A74593E1-1231-41BE-A5DF-693591F998E4
来自测试的userDictionary.count,28D817D9-B53D-47D8-A3EF-2F7DDE6460FC

最佳答案

我真的认为你需要/想用一个“放松”的部分。
ViewControllerA中添加此函数:

@IBAction func returnFromB(_ segue: UIStoryboardSegue) {
    if let vcDest = segue.destination as? ViewControllerA,
        let vcSource = segue.source as? ViewControllerB {
            // pass userDictionary from VCB back to VCA
            vcDest.userDictionary = vcSource.userDictionary
        print("unwind segue from B")
    }
}

然后,通过CTRL从视图控制器图标拖动到故事板中的ViewControllerA顶部的退出图标。给它一个segue标识符。
现在,在ViewControllerB中,您可以调用:
self.performSegue(withIdentifier: "unwindSegueBtoA", sender: self)

returnFromB()中的ViewControllerA函数将处理数据的传输。
下面是一个基本示例:https://github.com/DonMag/DataPass
另一个(可能更好的)选择是创建一个“数据管理器”类,并从每个控制器设置/获取该类中的数据,而不是来回传递。

关于ios - CollectionView失去对数据模型的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51503085/

相关文章:

ios - 钛焦点事件在 ios 上多次触发

SwiftUI : Using NavigationView leads to image and text gone

c# - wpf collectionview 多过滤器

ios - 我可以存储 paypal 信息,例如 paypal 的用户 ID 和密码以及用于自动充值功能的信用卡详细信息吗?

javascript - 这是正则表达式BUG吗?

android - 如何将 iOS 应用内购买同步到其他平台上的用户帐户

iOS插入数据库

ios - 异步请求如果失败了怎么办?

iOS : UICollectionView inside UIScrollView index not incremented