代码执行并不总是

时间:2018-04-09 14:29:00

标签: ios swift nsurlsessiondatatask

当应用启动时,我向api发送请求,应用程序开始接收数据。我使用委托方法,控制流,当它占用空字节时,它停止任务和会话。之后,我必须调用一些方法(UpdateInfoManager.createHouse()),其中包含方法链,它调用api并将数据解析为对象。但我执行时遇到了一些问题。例如,我启动我的应用程序10次,只有1或2次立即执行,其他8次我有无限加载:

extension ViewController: URLSessionTaskDelegate, URLSessionDelegate, URLSessionDataDelegate {


    func getLogBinData() {
        let session = URLSession(configuration: .default, delegate: self, delegateQueue: OperationQueue.main)
        if let url = URL(string: TaskManager.httpString + "log.bin") {
            var request = URLRequest(url: url)
            request.httpMethod = "GET"
            let task = session.dataTask(with: request)
            task.resume()
        }
    }

    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
        if data.first != 255 {
            fullData.append(data)
        } else {
            dataTask.cancel()
            session.invalidateAndCancel()
            UpdateInfoManager.createHouse(logData: self.fullData) { (complete) in
                DispatchQueue.main.async {
                    self.house = HouseManager.house
                    if let house = self.house {
                        self.nameLabel.text = house.houseName
                        self.menuController.house = house
                        self.menuController.roomsTableView.reloadData()
                        self.menuController.houseNameLabel.text = house.houseName
                        self.spinner.stopAnimating()
                        self.hideView.isHidden = true
                        self.view.isUserInteractionEnabled = true
                    }
                }
            }
        }
    }
}

但是我试图使用DispatchQueue.global()。asyncAfter(截止日期:.now()+ 0.1),并且它的工作原理,应用程序总是快速启动。但我认为这不是一个好的解决方案。为什么会这样?

        func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
            if data.first != 255 {
                fullData.append(data)
            } else {
                dataTask.cancel()
                session.invalidateAndCancel() 
                DispatchQueue.global().asyncAfter(deadline: .now() + 0.1) {
                    UpdateInfoManager.createHouse(logData: self.fullData) { (complete) in
                        DispatchQueue.main.async {
                            self.house = HouseManager.house
                            if let house = self.house {
                                self.nameLabel.text = house.houseName
                                self.menuController.house = house
                                self.menuController.roomsTableView.reloadData()
                                self.menuController.houseNameLabel.text = house.houseName
                                self.spinner.stopAnimating()
                                self.hideView.isHidden = true
                                self.view.isUserInteractionEnabled = true
                            }
                        }
                    }
                }

            }
        }

我还尝试在委托方法体中调用UpdateInfoManager.createHouse(),它也很有效。但我需要在这里打电话

更新

createHouse()方法代码:

class UpdateInfoManager: NSObject {

    static func createHouse(logData: Data, completion: @escaping ((Bool) -> ())) {
        TaskManager.getUserBinFileFromApi { (userData) in
            TaskManager.getDeviceBinFileFromApi(userData: userData, completion: { (userData, deviceData) in
                HouseManager.createDataObject(userData: userData, deviceData: deviceData, completion: { (house, data) in
                    HouseManager.createRooms(house: house, data: data, completion: { (house, data) in
                        DeviceManager.addDevicecToRooms(logData: logData, house: house, data: data, completion: { (data) in
                            DispatchQueue.main.async {
                                HouseManager.house = house
                                completion(true)
                            }
                        })
                    })
                })
            })
        }
    }

}  

1 个答案:

答案 0 :(得分:0)

@Sergey我的猜测是UpdateInfoManager.createHouse阻塞主线程因为你已经指定调用Delegate方法调用主线程检查下面的代码

URLSession(configuration: .default, delegate: self, delegateQueue: OperationQueue.main

替换为

URLSession(configuration: .default, delegate: self, delegateQueue:OperationQueue()

然后保持原样,

func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
        if data.first != 255 {
            fullData.append(data)
        } else {
            dataTask.cancel()
            session.invalidateAndCancel()
            UpdateInfoManager.createHouse(logData: self.fullData) {[weak self] (complete) in
                DispatchQueue.main.async {
                    self?.house = HouseManager.house
                    if let house = self?.house {
                        self?.nameLabel.text = house.houseName
                        self?.menuController.house = house
                        self?.menuController.roomsTableView.reloadData()
                        self?.menuController.houseNameLabel.text = house.houseName
                        self?.spinner.stopAnimating()
                        self?.hideView.isHidden = true
                        self?.view.isUserInteractionEnabled = true
                    }
                }
            }
        }
    }