我在一个单独的类中有以下方法:
class API: NSObject {
var data = NSData()
var delegate: APIProtocol?
func getItems(callback: (Array<Image>) -> ()) {
let urlPath: NSString = "http://localhost:3000/files"
let url = NSURL(string: urlPath)
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Accept")
let config = NSURLSessionConfiguration.defaultSessionConfiguration() as NSURLSessionConfiguration
let session = NSURLSession(configuration: config) as NSURLSession
var dataTask = NSURLSessionDataTask()
dataTask = session.dataTaskWithRequest(request) { (data, response, error) in
if (error == nil) {
println("API at URL \(url)")
let responseArray = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: nil) as NSArray
var images = Image[]()
for item: AnyObject in responseArray {
var location = Image(dict: item as NSDictionary)
images.append(location)
}
var img = images[0] as Image
callback(images)
//self.delegate?.didReceiveResponse(responseArray)
}
}
dataTask.resume()
}
}
在tableView
内拨打self.tableView.reloadData()
之前,我无法重新加载callback()
,直到我在其周围添加了dispatch_async()
。
我的问题是:
1)如果没有它,为什么它不能正常工作呢?现在我做正确的事情是它能正确地刷新tableView
吗?
2)是否有另一种方法可以让它工作而无需在主队列上添加调度?
api.getItems() { (theArray) in
dispatch_async(dispatch_get_main_queue(), {
self.images = theArray
self.tableView.reloadData()
if (viaPullToRefresh) {
self.refreshControl.endRefreshing()
}
})
}
答案 0 :(得分:6)
创建NSURLSession时,您可以指定委托/完成队列。如果您没有指定队列
会话创建一个用于执行所有操作的串行操作队列 委托方法调用和完成处理程序调用。
因此,这意味着您的回调将在专用串行队列上调用。现在,必须在主队列上更新所有UI,这就是tableView.reloadData()
无效的原因。
要删除对main_queue的调度调用,请像这样创建会话
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(), delegate: nil, delegateQueue: NSOperationQueue.mainQueue())