如何解决委托方法不会第二次被调用
我正在构建一个简单的货币转换器应用程序。打开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....
}
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 举报,一经查实,本站将立刻删除。