我有一个类BaseViewController,它具有以下功能(AKSwiftSlideMenu):
func openViewControllerBasedOnIdentifier(_ strIdentifier:String){
let destViewController : UIViewController = self.storyboard!.instantiateViewController(withIdentifier: strIdentifier)
let topViewController : UIViewController = self.navigationController!.topViewController!
if (topViewController.restorationIdentifier! == destViewController.restorationIdentifier!){
print("Same VC")
} else {
self.navigationController!.pushViewController(destViewController, animated: true)
}
}
有一个基于BaseViewController的视图控制器类可以进行登录检查,并包含一些控制器,包括2个文本字段控制器和一个按钮。以下代码附加到按钮的IBAction:
@IBAction func btn_login_pressed(_ sender: Any) {
//self.openViewControllerBasedOnIdentifier("logged")
var request = URLRequest(url: URL(string: "https://someURL/login?Username="+(text_email.text)!+"&Password="+(text_password.text)!)!)
request.httpMethod = "POST"
let postString = ""
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { // check for fundamental networking error
print("error=\(String(describing: error))")
return
}
if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 { // check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(String(describing: response))")
}
let responseString = String(data: data, encoding: .utf8)
let dict = self.convertToDictionary(text: responseString!)
let status:Int = dict?["Status"] as! Int
if(status==0){
print("fail")
} else {
self.openViewControllerBasedOnIdentifier("logged")
}
}
task.resume()
//self.openViewControllerBasedOnIdentifier("logged")
}
如果我在任务之前或在task.resume()之后使用self.openViewControllerBasedOnIdentifier,则一切正常,应用程序将打开新的视图控制器。另一方面,当我尝试在接收在线数据后使用该功能时,我也没有得到构建错误。代码运行,访问在线数据。 Dict得到它的价值。然后有很多等待,我在输出中得到以下消息:
2017-05-07 16:27:25.301 myApp [9788:3330252]此应用程序在从主线程访问引擎后从后台线程修改autolayout引擎。这可能导致引擎损坏和奇怪的崩溃。
有时会加载新视图,有时会失败。
另一方面,在获取在线登录数据之前,在task.resume()行之后写的东西似乎发生了。
所以我的问题是如何在获取在线数据后访问self.openViewControllerBasedOnIdentifier函数。
非常感谢任何帮助
答案 0 :(得分:2)
确保所有UI工作都在主线程上完成。尝试将代码包装在调度块中以使用主线程
user=> (ancestors clojure.lang.PersistentVector)
#{clojure.lang.IEditableCollection clojure.lang.ILookup
java.util.concurrent.Callable java.lang.Runnable clojure.lang.IMeta
java.lang.Comparable clojure.lang.IReduceInit
clojure.lang.IPersistentCollection clojure.lang.IHashEq java.lang.Iterable
clojure.lang.IReduce java.util.List clojure.lang.AFn clojure.lang.Indexed
clojure.lang.Sequential clojure.lang.IPersistentStack java.io.Serializable
clojure.lang.Reversible clojure.lang.Counted java.util.Collection
java.util.RandomAccess java.lang.Object clojure.lang.Seqable
clojure.lang.Associative clojure.lang.APersistentVector
clojure.lang.IKVReduce clojure.lang.IPersistentVector clojure.lang.IObj
clojure.lang.IFn}
当您发出网络请求时,它会在后台线程上异步运行。因此,当您收到响应并希望对您的用户界面执行某些操作时,您需要确保在主线程上完成此操作。
因为网络请求是异步的并且在后台线程上运行。您会注意到task.resume之前和之后的代码通常会在您获得响应之前运行,例如:
DispatchQueue.main.async {
// init your views here
let destViewController : UIViewController = self.storyboard!.instantiateViewController(withIdentifier: strIdentifier)
let topViewController : UIViewController = self.navigationController!.topViewController!
if (topViewController.restorationIdentifier! == destViewController.restorationIdentifier!){
print("Same VC")
} else {
self.navigationController!.pushViewController(destViewController, animated: true)
}
}
此处的预期输出为:
之前的异步
后异步
收到回复