委托方法不会被第二次调用
delegate method does not get called second time
我正在构建一个简单的货币转换器应用程序。当 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, currency1: String, price2: 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
}
}
...
}
最后,货币ViewController.swift:
var coinManager = CoinManager()
@IBAction func backButtonPressed(_ sender: UIBarButtonItem) {
dismiss(animated: true, completion: nil)
coinManager.getCoinPrice(for: "USD", "AZN", firstCall: false)
}
因此,当我启动该应用程序时,我在调试控制台中得到以下提示:
didUpdatePrice called
delegate:AUD
当我从 CurrencyViewController
调用 getCoinPrice()
时,委托方法没有被调用。当我在调试控制台中得到这个时,我知道我的代码通过委托函数行:
delegate:USD
我就是无法理解它。第二次调用时委托方法不起作用。即使它被相同的算法调用
能分享一下CoinManager的完整代码吗?我看到这部分
if firstCall {
...
}
也许这里有一些块逻辑或未处理的情况?你能分享协议的完整代码吗?
也尝试在这段代码之前打印一些东西:
if error != nil {
self.delegate?.didFailWithError(error: error!)
return
}
这是因为您在 CurrencyViewController
中创建了 CoinManager
的新对象,其中 delegate
未设置。因此,每次创建 CoinManager
.
的新实例时,都必须设置 delegate
@IBAction func backButtonPressed(_ sender: UIBarButtonItem) {
dismiss(animated: true, completion: nil)
coinManager.delegate = self
coinManager.getCoinPrice(for: "USD", "AZN", firstCall: false)
}
更新:因此,上述解决方案需要您使委托符合 CurrencyViewController
。如果您正在寻找替代解决方案,您应该将 ViewController
中 coinManager
的实例传递给 CurrencyViewController
。为此,您需要更新以下内容。
在CurrencyViewController
中:
class CurrencyViewController: UIViewController {
var coinManager: CoinManager! // you can optional unwrap if you intent to use CurrencyViewController without coinManager
//...
在ViewController
中:
currencyViewController.coinManager = coinManager // passing the instance of coinManager
我正在构建一个简单的货币转换器应用程序。当 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, currency1: String, price2: 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
}
}
...
}
最后,货币ViewController.swift:
var coinManager = CoinManager()
@IBAction func backButtonPressed(_ sender: UIBarButtonItem) {
dismiss(animated: true, completion: nil)
coinManager.getCoinPrice(for: "USD", "AZN", firstCall: false)
}
因此,当我启动该应用程序时,我在调试控制台中得到以下提示:
didUpdatePrice called
delegate:AUD
当我从 CurrencyViewController
调用 getCoinPrice()
时,委托方法没有被调用。当我在调试控制台中得到这个时,我知道我的代码通过委托函数行:
delegate:USD
我就是无法理解它。第二次调用时委托方法不起作用。即使它被相同的算法调用
能分享一下CoinManager的完整代码吗?我看到这部分
if firstCall {
...
}
也许这里有一些块逻辑或未处理的情况?你能分享协议的完整代码吗?
也尝试在这段代码之前打印一些东西:
if error != nil {
self.delegate?.didFailWithError(error: error!)
return
}
这是因为您在 CurrencyViewController
中创建了 CoinManager
的新对象,其中 delegate
未设置。因此,每次创建 CoinManager
.
delegate
@IBAction func backButtonPressed(_ sender: UIBarButtonItem) {
dismiss(animated: true, completion: nil)
coinManager.delegate = self
coinManager.getCoinPrice(for: "USD", "AZN", firstCall: false)
}
更新:因此,上述解决方案需要您使委托符合 CurrencyViewController
。如果您正在寻找替代解决方案,您应该将 ViewController
中 coinManager
的实例传递给 CurrencyViewController
。为此,您需要更新以下内容。
在CurrencyViewController
中:
class CurrencyViewController: UIViewController {
var coinManager: CoinManager! // you can optional unwrap if you intent to use CurrencyViewController without coinManager
//...
在ViewController
中:
currencyViewController.coinManager = coinManager // passing the instance of coinManager