【问题标题】:CollectionView is being called before the complete execution of function called in ViewDidLoad() in swift在快速执行 ViewDidLoad() 中调用的函数之前调用 CollectionView
【发布时间】:2021-02-27 10:44:14
【问题描述】:

我在 viewDidLoad 方法中有这样的函数调用

override func viewDidLoad(){
super.viewDidLoad()
    getSubCategories()
}

而func定义如下

func getSubCategories(){        
    let parameters = xx
    let url = URL(string: "xx")!
    let session = URLSession.shared
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    
    do {

        request.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
    } catch let error {
        print(error.localizedDescription)
    }
    
    let task = session.dataTask(with: request as URLRequest, completionHandler: { [self] data, response, error in
        do {
            if (try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any]) != nil {

函数执行到这里然后跳转到task.resume跳过之后的代码

        subCategoryModel = try JSONDecoder().decode(SubCategoryModel.self, from: data)
        print(subCategoryModel!)
            }
        } catch let error {
            print(error)
        }
    })
    task.resume()

在解码数据之前,collectionViews 开始重新加载并显示值为 nil 的错误。 我已经在 viewdidload 中设置了委托和数据源。如何编写解码过程后加载集合视图的代码。

【问题讨论】:

  • session 是异步调用,task.resume 启动调用从服务器获取数据,一旦你收到你的数据闭包块被调用,然后你需要处理你的场景。 stackoverflow.com/questions/25203556/…
  • 只需在 print(subCategoryModel!) 行之后的集合视图上(在主线程上)调用 reloadData。而你所有的JSONSerialization 选项都是毫无意义的。服务器不关心漂亮打印的 JSON,mutableContainers 在 Swift 中完全没用。

标签: swift function uicollectionview


【解决方案1】:

DataTask 正在后台运行。所以它与其余的代码并不并行。如果您希望下面的部分在之后运行,请执行以下操作:

你会等待的班级:

class Observable<T> {
    var didChange: ((T?) -> Void)?
    var value: T? {
        didSet {
            // This is for the code to go back to the main thread before running
            DispatchQueue.main.async { 
                self.didChange?(self.value)
            }
        }
    }

    init(_ value: T? = nil) {
        self.value = value
    }

    deinit {
        didChange = nil
    }
}

现在在您的ViewController

class MyViewController: UIViewController {
    var observable = Observable<Data?>()

    override func viewDidLoad(){
        super.viewDidLoad()
        getSubCategories()
    }

    func getSubCategories() {
        obervable.didSet = { data in 
             // your code that will run after goes here
        }
        // your code that will run before goes here

        // your request
        let task = session.dataTask(with: request as URLRequest, completionHandler: { [self] data, response, error in
            do {
                if (try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any]) != nil {

                 // this will trigger the code that needs to run after and give you the data you need
                 self.obervable.value = data
                }
            } catch {
            }
         }
    }
}
        

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-15
    • 1970-01-01
    • 1970-01-01
    • 2014-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多