reloadData 不会将完成处理程序的 dispatch_async 中的 table 视图重新加载到主线程
reloadData doesn't reload the table view in completion handler's dispatch_async to the main thread
我正在使用 UISearchBar 在 iOS 8(模拟器)中使用 Swift 1.2 执行 MKLocalSearch。
我在完成处理程序中得到返回的结果(通过 printlns 在控制台中查看),但是当我尝试执行异步调用主线程以重新加载 table 视图时,没有任何反应。
如果我在搜索栏中单击取消,它会在 table 视图中显示结果。看来我在执行异步重新加载数据调用时出错了。
这是我的 UISearchBarDelegate searchBarSearchButtonClicked 代码:
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
searchBar.resignFirstResponder()
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
if let currentLocation = appDelegate.currentLocation {
searchResults.removeAll()
let request = MKLocalSearchRequest()
request.naturalLanguageQuery = searchBar.text
request.region = MKCoordinateRegionMakeWithDistance(currentLocation.coordinate, 200, 200)
let search = MKLocalSearch(request: request)
search.startWithCompletionHandler({ (response: MKLocalSearchResponse!, error: NSError!) -> Void in
if error != nil {
println("Error occured in search: \(error.localizedDescription)")
} else if response.mapItems.count == 0 {
println("No matches found")
} else {
println("Matches found")
for item in response.mapItems as! [MKMapItem] {
println("Name = \(item.name)")
self.searchResults.append(item)
}
println("Matching items = \(self.searchResults.count)")
}
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.searchTableView.reloadData() // doesn't do anything
})
})
}
}
这是我在控制台中看到的示例,但 table 视图仍然是空的:
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
searchBarSearchButtonClicked called
startWithCompletionHandler called
Matches found
Name = Artichoke Basille's Pizza
Name = Scott's Pizza Tours
Name = Waldy's Wood Fired Pizza & Penne
Name = Trattoria Zero Otto Nove
Name = Vezzo Thin Crust Pizza
Name = Grimaldi's
Name = Tappo Thin Crust Pizza
Name = Mozzarelli's
Name = NY Pizza Suprema
Name = Otto Enoteca Pizzeria
Matching items = 10
numberOfRowsInSection called
cellForRowAtIndexPath called, name = Artichoke Basille's Pizza
cellForRowAtIndexPath called, name = Scott's Pizza Tours
cellForRowAtIndexPath called, name = Waldy's Wood Fired Pizza & Penne
cellForRowAtIndexPath called, name = Trattoria Zero Otto Nove
cellForRowAtIndexPath called, name = Vezzo Thin Crust Pizza
cellForRowAtIndexPath called, name = Grimaldi's
cellForRowAtIndexPath called, name = Tappo Thin Crust Pizza
cellForRowAtIndexPath called, name = Mozzarelli's
cellForRowAtIndexPath called, name = NY Pizza Suprema
cellForRowAtIndexPath called, name = Otto Enoteca Pizzeria
我在这里做错了什么?
谢谢!
编辑:添加了更多 printlns 以显示不同的 table 委托方法被调用并更新了上面的控制台输出。
好的,所以您的日志似乎显示 cellForRowAtIndexPath
被正确调用并且它正在成功检索数据。所以,现在的问题是为什么您没有在 table 中看到它。
要么 cellForRowAtIndexPath
没有填充正确的控件,要么这些控件的 frame
(或 alpha
或类似的东西)设置为您看不到数据。通过点击 Xcode:
中的 "pause" 按钮暂停执行
并在新视图调试器中查看视图布局:
或在 (lldb)
提示符下键入 po [[UIWindow keyWindow] recursiveDescription]
。确认您要使用记录的数据填充的文本标签的 frame
。
问题是无法从主线程调用 UITableView.reloadData()
。相反,您需要安排自己的线程并异步调用它。
因此,首先您需要安排自己创建的线程并从后台调用它。您可以使用以下代码重新加载您的 UITableView 数据。
let concurrentQueue: dispatch_queue_t = dispatch_queue_create("MyQueue", nil)
dispatch_async(concurrentQueue) {
// update some UI
dispatch_async(dispatch_get_main_queue()) {
// update some UI
self.tableView.reloadData()
}
}
好吧,这肯定会重新加载您的 UITableView 数据。据我所知,我正在使用这种方法。如果您发现任何其他更方便的方法,请告诉我。
我正在使用 UISearchBar 在 iOS 8(模拟器)中使用 Swift 1.2 执行 MKLocalSearch。
我在完成处理程序中得到返回的结果(通过 printlns 在控制台中查看),但是当我尝试执行异步调用主线程以重新加载 table 视图时,没有任何反应。
如果我在搜索栏中单击取消,它会在 table 视图中显示结果。看来我在执行异步重新加载数据调用时出错了。
这是我的 UISearchBarDelegate searchBarSearchButtonClicked 代码:
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
searchBar.resignFirstResponder()
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
if let currentLocation = appDelegate.currentLocation {
searchResults.removeAll()
let request = MKLocalSearchRequest()
request.naturalLanguageQuery = searchBar.text
request.region = MKCoordinateRegionMakeWithDistance(currentLocation.coordinate, 200, 200)
let search = MKLocalSearch(request: request)
search.startWithCompletionHandler({ (response: MKLocalSearchResponse!, error: NSError!) -> Void in
if error != nil {
println("Error occured in search: \(error.localizedDescription)")
} else if response.mapItems.count == 0 {
println("No matches found")
} else {
println("Matches found")
for item in response.mapItems as! [MKMapItem] {
println("Name = \(item.name)")
self.searchResults.append(item)
}
println("Matching items = \(self.searchResults.count)")
}
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.searchTableView.reloadData() // doesn't do anything
})
})
}
}
这是我在控制台中看到的示例,但 table 视图仍然是空的:
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
numberOfRowsInSection called
searchBarSearchButtonClicked called
startWithCompletionHandler called
Matches found
Name = Artichoke Basille's Pizza
Name = Scott's Pizza Tours
Name = Waldy's Wood Fired Pizza & Penne
Name = Trattoria Zero Otto Nove
Name = Vezzo Thin Crust Pizza
Name = Grimaldi's
Name = Tappo Thin Crust Pizza
Name = Mozzarelli's
Name = NY Pizza Suprema
Name = Otto Enoteca Pizzeria
Matching items = 10
numberOfRowsInSection called
cellForRowAtIndexPath called, name = Artichoke Basille's Pizza
cellForRowAtIndexPath called, name = Scott's Pizza Tours
cellForRowAtIndexPath called, name = Waldy's Wood Fired Pizza & Penne
cellForRowAtIndexPath called, name = Trattoria Zero Otto Nove
cellForRowAtIndexPath called, name = Vezzo Thin Crust Pizza
cellForRowAtIndexPath called, name = Grimaldi's
cellForRowAtIndexPath called, name = Tappo Thin Crust Pizza
cellForRowAtIndexPath called, name = Mozzarelli's
cellForRowAtIndexPath called, name = NY Pizza Suprema
cellForRowAtIndexPath called, name = Otto Enoteca Pizzeria
我在这里做错了什么?
谢谢!
编辑:添加了更多 printlns 以显示不同的 table 委托方法被调用并更新了上面的控制台输出。
好的,所以您的日志似乎显示 cellForRowAtIndexPath
被正确调用并且它正在成功检索数据。所以,现在的问题是为什么您没有在 table 中看到它。
要么 cellForRowAtIndexPath
没有填充正确的控件,要么这些控件的 frame
(或 alpha
或类似的东西)设置为您看不到数据。通过点击 Xcode:
并在新视图调试器中查看视图布局:
或在 (lldb)
提示符下键入 po [[UIWindow keyWindow] recursiveDescription]
。确认您要使用记录的数据填充的文本标签的 frame
。
问题是无法从主线程调用 UITableView.reloadData()
。相反,您需要安排自己的线程并异步调用它。
因此,首先您需要安排自己创建的线程并从后台调用它。您可以使用以下代码重新加载您的 UITableView 数据。
let concurrentQueue: dispatch_queue_t = dispatch_queue_create("MyQueue", nil)
dispatch_async(concurrentQueue) {
// update some UI
dispatch_async(dispatch_get_main_queue()) {
// update some UI
self.tableView.reloadData()
}
}
好吧,这肯定会重新加载您的 UITableView 数据。据我所知,我正在使用这种方法。如果您发现任何其他更方便的方法,请告诉我。