【问题标题】:Swift Initialization class and working with Parameters and MethodsSwift 初始化类和使用参数和方法
【发布时间】:2020-12-15 04:29:13
【问题描述】:

我是 swift 的新手,我的问题对你们大多数人来说可能是愚蠢的。但无论如何,我都在尝试边做边学。这是我的问题。 我有一个模型:

import Foundation
import Firebase

struct special {
    let name: String
    let position: Int
    let imageURL: String?
}


class SpecialList {
    
    var specialList: [special] = []

    init() {        
        
    }
    
    func loadSpecial () {
        db.collection("special").getDocuments { (querySnapshot, error) in
            if let e = error {
                print("Error\(e)")
            } else {
                if let snapshotDocuments = querySnapshot?.documents {
                    for doc in snapshotDocuments {
                        let data = doc.data()
                        if let name = data["name"] as? String, let position = data["position"] as? Int, let imageURL = data["imageURL"] as? String {
                            let newList = special(name: name, position: position, imageURL: imageURL)
                            self.specialList.append(newList)
                        }
                    }
                }
            }
        }
    }    
}

我正在尝试在 ViewController 中实现它:

var specialList = SpecialList()

override func viewDidLoad() {
specialList.loadSpecial()
print(specialList.specialList)
}

实际上我需要的是从 firebase 检索的数据。我试图将它保存在var specialList: [special] = []但它总是空的。我认为我应该在 init() 中做一些事情,但没有找到正确的方法。

附:从firebase加载工作正常。已打印数据进行检查。

数据应该在collectionView中

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return specialList.specialList.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SpecialCell", for: indexPath as IndexPath) as! SpecialCollectionViewCell
        
        if let imageURL = specialList.specialList[indexPath.row].imageURL {
            let url = URL(string: imageURL)
            cell.specialPic.kf.setImage(with: url) // download foto
        }
        cell.specialName.text = specialList.specialList[indexPath.row].name
        return cell
    }

【问题讨论】:

  • 在 self.specialList.append(newList) 上设置断点并检查是否调用
  • 在这个函数里面它的 append specialList 并且工作正常。但是通过在 ViewController 中实现它是空的。
  • 它是异步工​​作的,因此您必须在加载数据后对其进行处理。
  • 那么,问题不在于我的班级SpecialList?我应该玩 DispatchQueue.main.async

标签: swift class methods properties initialization


【解决方案1】:
func loadSpecial (completion: @escaping (Bool) -> Void) {
    db.collection("special").getDocuments { (querySnapshot, error) in
        if let e = error {
            print("Error\(e)")
            completion(false)
        } else {
            if let snapshotDocuments = querySnapshot?.documents {
                for doc in snapshotDocuments {
                    let data = doc.data()
                    if let name = data["name"] as? String, let position = data["position"] as? Int, let imageURL = data["imageURL"] as? String {
                        let newList = special(name: name, position: position, imageURL: imageURL)
                        self.specialList.append(newList)
                    }
                }
                completion(true)
            }
            completion(false)
        }
    }
}

为您的方法添加补全

在 VC 中这样做:

override func viewDidLoad() {
    super.viewDidLoad()
    specialList.loadSpecial(completion: { [weak self] success in
        self.collectionView.reloadData()
    })
}

如果集合实现是对的,你会看到的

【讨论】:

  • 在这个函数里面它的 append specialList 并且工作正常。但是通过在 ViewController 中实现它是空的。
  • 你会看到它在 print(self?. specialList.specialList) } }
  • 现在它打印结果(带有 3 个警告),但最后结果应该在集合视图中。但是还是有空的。我尝试了 collectionView.reloadData(),但没有帮助。我更新了我的问题,最后应该将数据存储在哪里
  • 更新后出错。
  • 但它是这样工作的:specialList.loadSpecial { (Bool) in self.collectionView.reloadData() }
【解决方案2】:

在你的 append 语句和 print 语句中放置一个断点,看看哪个是第一个被调用的。 print 语句可能会在获取数据之前被调用。

【讨论】:

    【解决方案3】:

    如果有人有同样的问题。使用委托解决它的最佳方法。我已经添加了额外的:

    protocol SpecialListUpdateDelegate {
        func didUpdate(sender: SpecialList)
    }
    

    在我的班级 SpecialList 中:

    var delegate: SpecialListUpdateDelegate?
    

    在 loadspecial() 中:

    self.delegate?.didUpdate(sender: self)
    

    在VC中为VC添加协议:SpecialListUpdateDelegate

    在 viewDidLoad 中:

    specialList.delegate = self
    

    最后一个实现函数:

    func didUpdate(sender: SpecialList) {
            DispatchQueue.main.async {
                self.collectionView.reloadData()
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多