Swift 3,成功传递数据但var在使用时返回nil

时间:2017-03-19 17:04:21

标签: ios swift

所以这是来自VC1的代码并将数据传递给VC2。

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        selectedArtist = artists[indexPath.item]
        performSegue(withIdentifier: "artistToArtSegue", sender: self)

    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "artistToArtSegue" {
            let artCollectionController = ArtCollectionController()
            artCollectionController.artist = selectedArtist
            artCollectionController.selectedArtist = selectedArtist
        }
    }

VC2中的这些代码将打印数据

class ArtCollectionController: UICollectionViewController {

    var artist = Artist() {
        didSet{
            print(artist.artistId ?? "did not work")
            print(artist.name ?? "what name?")
        }
    }
    var selectedArtist = Artist()

但是当我在VC2中使用以下测试代码中的变量时。他们返回零。

func fetchArtForArtist() {
        guard let artistId = selectedArtist.artistId else {return}
        print(artistId)
        let fanRef = FIRDatabase.database().reference().child("art_ref").child(artistId)
        fanRef.observeSingleEvent(of: .childAdded, with: { (snapshot) in
            let artId = snapshot.key
            print(artId)
//            let dataRef = FIRDatabase.database().reference().child(artId)
//            dataRef.observe(.value, with: { (snapshot) in
//                let dictionary = snapshot.value as? [String: AnyObject]
//                //let art =

//            }, withCancel: nil)
        }, withCancel: nil)

    }

@IBAction func testButton(_ sender: UIBarButtonItem) {
        print(selectedArtist.name ?? "no name")
        print(12345)
    }
 override func viewDidAppear(_ animated: Bool) {
        selectedArtist = artist
        print(artist.name ?? "non")
        print(selectedArtist.artistId ?? "no id")

    }
    override func viewDidLoad() {
        super.viewDidLoad()
        fetchArtForArtist()
        selectedArtist = artist
        print(artist.name ?? "non")
        print(selectedArtist.artistId ?? "no id")


    }

我在storyBoard中这样做。我甚至使用2个vars看看是否有区别。我不明白为什么数据成功传递给VC2到几个变量,但是当使用变量时它返回一个nil。请帮忙。

3 个答案:

答案 0 :(得分:3)

其他答案都很好,但我更喜欢略有不同的方法:

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

    case let artCollectionController as ArtCollectionController:
        artCollectionController.artist = selectedArtist
        artCollectionController.selectedArtist = selectedArtist
    case let otherViewController as OtherViewController:
        //Code for some other case
    }
}

通过使用switch语句,您有prepareForSegue可以干净地处理多个不同的段。

case let构造是一个很酷的技巧,只有在交换机中的变量可以是所需类型的情况下才执行该情况。如果可以强制转换,则会创建所需类型的局部变量。

我更喜欢根据目标视图控制器的类来决定要执行的代码,因为它比使用segue标识符更不易碎。如果您忘记设置segue标识符,或稍后将第二个segue添加到同一类型的视图控制器,或者在标识符的名称中输入错误,则该代码将无法正常工作。但是,如果类名中有拼写错误,则编译器会抛出错误。

答案 1 :(得分:2)

因为您在artist的新实例上设置了ArtCollectionController属性,该实例在prepareForSegue函数退出时被销毁:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "artistToArtSegue" {
        let artCollectionController = ArtCollectionController() // created
        artCollectionController.artist = selectedArtist
        artCollectionController.selectedArtist = selectedArtist
        // destroyed here
    }
}

请改为尝试:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "artistToArtSegue",
        let artCollectionController = segue.destination as? ArtCollectionController
    {
        artCollectionController.artist = selectedArtist
        artCollectionController.selectedArtist = selectedArtist
    }
}

答案 2 :(得分:1)

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "artistToArtSegue" {
        let artCollectionController = segue.destination as! ArtCollectionController
        artCollectionController.artist = selectedArtist
        artCollectionController.selectedArtist = selectedArtist
    }
}

试试这个,你又创建了一个ArtCollectionController而不是传递数据来实现一个