微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

委托方法不会第二次被调用

如何解决委托方法不会第二次被调用

我正在构建一个简单的货币转换器应用程序。打开ViewController时,它会从CoinManager.swift调用一个函数

class ViewController: UIViewController {
    var coinManager = CoinManager()

        override func viewDidLoad() {
           super.viewDidLoad()
            
            coinManager.delegate = self
            coinManager.getCoinPrice(for: "AUD","AZN",firstCall: true)
        }
...
}

CoinManager.swift:

protocol CoinManagerDelegate {
    func didUpdatePrice(price1: Double,currency1: String,price2: Double,currency2: String)
    func tellTableView(descriptions: [String],symbols: [String])
    func didFailWithError(error: Error)
}

struct CoinManager {

    var delegate: CoinManagerDelegate?
    let baseURL = "https://www.cbr-xml-daily.ru/daily_json.js"

    func getCoinPrice (for currency1: String,_ currency2: String,firstCall: Bool) {

        if let url = URL(string: baseURL) {

            let session = URLSession(configuration: .default)
            let task = session.dataTask(with: url) { (data,response,error) in
                if error != nil {
                    self.delegate?.didFailWithError(error: error!)
                    return
                }

                if let safeData = data {
                    if let coinData = self.parseJSON(safeData) {
                        
                        if firstCall {
                            var descriptions = [""]
                            let listofCoins = Array(coinData.keys)
                            
                            for key in listofCoins {
                                descriptions.append(coinData[key]!.Name)
                            }
                            descriptions.removeFirst()
                            self.delegate?.tellTableView(descriptions: descriptions,symbols: listofCoins)
                        }

                        if let coinInfo1 = coinData[currency1] {
                            let value1 = coinInfo1.Value
                            if let coinInfo2 = coinData[currency2] {
                                let value2 = coinInfo2.Value

//this line does not do anything the second time I call getCoinPrice: 
                                self.delegate?.didUpdatePrice(price1: value1,currency1: currency1,price2: value2,currency2: currency2) 
//And this one does work
                                print("delegate:\(currency1)") 
                            } else {
                                print("no name matches currency2")
                            }
                        } else {
                            print("no name matches currency1")
                        }
                    }
                }
            }
            task.resume()
        }
    }
func ParseJSON....
}

调用方法(ViewController.swift):

extension ViewController: CoinManagerDelegate {

    func didUpdatePrice(price1: Double,currency2: String) {
        
        print("didUpdatePrice called")
        
        dispatchQueue.main.async {
            let price1Asstring = String(price1)
            let price2Asstring = String(price2)
            self.leftTextField.text = price1Asstring
            self.rightTextField.text = price2Asstring
            self.leftLabel.text = currency1
            self.rightLabel.text = currency2
        }
    }
...
}

最后是CurrencyViewController.swift:


var coinManager = CoinManager()

   @IBAction func backButtonpressed(_ sender: UIBarButtonItem) {
        dismiss(animated: true,completion: nil)
        coinManager.getCoinPrice(for: "USD",firstCall: false)
    }

因此,当我启动该应用程序时,我会在调试控制台中关注以下内容

didUpdatePrice called
delegate:AUD

当我从getCoinPrice()调用CurrencyViewController时,不会调用委托方法。我知道我的代码在调试控制台中通过委托函数行完成:

delegate:USD

我只是不能把头缠住它。当第二次被调用时,委托方法不起作用。即使使用相同的算法调用

解决方法

这是因为要在未设置CoinManager的{​​{1}}中创建CurrencyViewController的新对象。因此,每次创建新的delegate实例时,都必须设置delegate

CoinManager

更新:因此,上述解决方案将要求您在@IBAction func backButtonPressed(_ sender: UIBarButtonItem) { dismiss(animated: true,completion: nil) coinManager.delegate = self coinManager.getCoinPrice(for: "USD","AZN",firstCall: false) } 中进行委托符合。如果您正在寻找替代解决方案,则可能应该将CurrencyViewController中的coinManager实例传递给ViewController。为此,您需要更新这些内容。

CurrencyViewController中:

CurrencyViewController

class CurrencyViewController: UIViewController { var coinManager: CoinManager! // you can optional unwrap if you intent to use CurrencyViewController without coinManager //... 中:

ViewController
,

您可以共享CoinManager的完整代码吗?我看到这部分

if firstCall {
  ...
}

也许这里有一些块逻辑或未处理的情况?您可以共享完整的协议代码吗?

也请尝试在此代码之前打印一些内容:

if error != nil {
    self.delegate?.didFailWithError(error: error!)
        return
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。