我只是第一次使用Swift和Xcode 6 beta学习Ios编程。
我正在制作一个简单的测试应用程序,该应用程序应调用API,然后以编程方式将其选择到另一个视图以呈现所检索到的信息。
问题是segue。在我的委托方法中didReceiveAPIResults
,成功检索所有内容后,我将:
println("--> Perform segue")
performSegueWithIdentifier("segueWhenApiDidFinish", sender: nil)
当应用运行时,控制台将输出--> Perform segue
,但是在将应用实际定位到下一个视图之前,大约有5-10秒的延迟。在此期间,所有UI组件均被冻结。
我有点想找出为什么segue不会立即发生的原因,或者如何调试它!
这是Full View控制器:
import UIKit
class ViewController: UIViewController, APIControllerProtocol {
@lazy var api: APIController = APIController(delegate: self)
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func didReceiveAPIResults(results: NSDictionary) {
println(results)
println("--> Perform segue")
performSegueWithIdentifier("segueWhenApiDidFinish", sender: nil)
}
@IBAction func getData(sender : AnyObject){
println("--> Get Data from API")
api.getInfoFromAPI()
}
}
还有我的API控制器:
import UIKit
import Foundation
protocol APIControllerProtocol {
func didReceiveAPIResults(results: NSDictionary)
}
class APIController: NSObject {
var delegate: APIControllerProtocol?
init(delegate: APIControllerProtocol?) {
self.delegate = delegate
}
func getInfoFromAPI(){
let session = NSURLSession.sharedSession()
let url = NSURL(string: "https://itunes.apple.com/search?term=Bob+Dylan&media=music&entity=album")
let task = session.dataTaskWithURL(url, completionHandler: {data, response, error -> Void in
if(error) {
println("There was a web request error.")
return
}
var err: NSError?
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions. MutableContainers, error: &err) as NSDictionary
if(err?) {
println("There was a JSON error.")
return
}
self.delegate?.didReceiveAPIResults(jsonResult)
})
task.resume()
}
}
更新:根据Ethan的回答进行了这项工作。以下是最终获得所需行为的确切代码。我需要分配that
才能self
访问dispatch_async
块内的self 。
let that = self
if(NSThread.isMainThread()){
self.delegate?.didReceiveAPIResults(jsonResult)
}else
{
dispatch_async(dispatch_get_main_queue()) {
println(that)
that.delegate?.didReceiveAPIResults(jsonResult)
}
}
有趣的是,如果删除该println(that)
行,此代码将不起作用!(构建失败,并显示could not find member 'didReceiveAPIResults'
)。如果有人可以对此发表评论,这很好奇。
我相信您在致电时不在主线程上
self.delegate?.didReceiveAPIResults(jsonResult)
如果您好奇是否在主线程上,可以通过练习NSThread.isMainThread()
返回布尔值。
无论如何,如果事实证明您不在主线程上,那一定是!为什么?因为后台线程没有优先级,并且将等待很长时间才能看到结果,这与主线程不同,后者对系统来说是高优先级。这是要做什么...getInfoFromAPI
替换
self.delegate?.didReceiveAPIResults(jsonResult)
和
dispatch_sync(dispatch_get_main_queue())
{
self.delegate?.didReceiveAPIResults(jsonResult)
}
在这里,您正在使用GCD获取主队列并在主线程上的块内执行UI更新。
但是dispatch_sync(dispatch_get_main_queue())
请耐心等待,因为如果您已经在主线程上,则调用将永远等待(也就是冻结您的应用程序)...因此请注意。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句