>我正在为一个教会制作一个简单的应用程序,该应用程序从成员的MySQL数据库中检索随机名称,并将"检索名称"按钮文本设置为成员名称。它大部分工作,但第一次点击按钮不会改变按钮文本,尽管打印显示它正在从数据库中正确检索名称。当我反复点击时,有时文本会更改,有时不会。我想这可能是因为数据尚未加载,并且 Swift 正在过快地处理下一段代码。有没有适当的方法可以延迟到数据加载?谢谢!
以下是应用代码:
//
// ViewController.swift
// Grace Tabernacle Prayer App
//
// Created by Nico Pampaloni on 1/14/17.
// Copyright © 2017 Pampaloni Code. All rights reserved.
//
// Simple app to retrieve a random name from a MySQL database and display that name as the button text.
import UIKit
class ViewController: UIViewController {
@IBAction func buttonPressed(_ sender: UIButton) {
// set URL of php script as NSURL
let scriptUrl = "https://gtinternal.com/api/getname.php"
let myUrl = NSURL(string: scriptUrl);
let request = NSMutableURLRequest(url:myUrl! as URL);
// use HTTP GET to retreive request data
request.httpMethod = "GET"
// store the GET response and convert to a String
let task = URLSession.shared.dataTask(with: request as URLRequest) {
data, response, error in
if error != nil
{
print("error=(error)")
return
}
let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)!
let memberName = responseString as String
print(responseString)
// change Button text to retrieved string
sender.setTitle(memberName, for: .normal)
}
task.resume()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
这里的问题是任务内部的代码作为闭包块的一部分异步执行。这意味着它不在主线程上运行。然后尝试从后台线程更新 UI,这将产生意外的结果。始终将 UI 代码放在主线程上。当您设置标题时sender
将该代码放在一个块中以在主线程上执行。
。
DispatchQueue.main.async {
// change Button text to retrieved string
sender.setTitle(memberName, for: .normal)
}
。