reloadData不会将完成处理程序的dispatch_async中的表视图重新加载到主线程

时间:2015-07-31 04:17:05

标签: ios multithreading swift mapkit reloaddata

我正在使用UISearchBar在iOS 8(模拟器)中使用Swift 1.2进行MKLocalSearch。

我在完成处理程序中返回结果(通过printlns在控制台中看到它),但是当我尝试执行异步调用时,主线程重新加载表视图没有任何反应。

如果我在搜索栏中单击“取消”,它将在表格视图中显示结果。看来我正在做异步重载数据调用错误。

这是我的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
            })
        })
    }

}

这是我在控制台中看到的一个例子,但是仍有一个空表视图:

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,以显示正在调用的不同表委托方法并更新上面的控制台输出。

2 个答案:

答案 0 :(得分:1)

好的,所以你的日志似乎表明正在调用cellForRowAtIndexPath并且它已成功检索数据。所以,现在的问题是为什么你没有在表中看到它。

cellForRowAtIndexPath没有填充正确的控件,或frame(或alpha或类似的东西)设置这些控件,以便您无法查看数据。点击Xcode中的“暂停”按钮暂停执行:

enter image description here

并在新视图调试器中查看视图的布局:

enter image description here

或在po [[UIWindow keyWindow] recursiveDescription]提示符下键入(lldb)。使用您记录的数据确认填充的文本标签的frame

答案 1 :(得分:0)

问题是无法从主线程调用</tr>。而不是那样,你需要安排自己的线程并异步调用它。

因此,首先您需要安排自己创建的线程并从后台调用它。您可以使用以下代码重新加载UITableView数据。

UITableView.reloadData()

好吧,这肯定会重新加载你的UITableView数据。据我所知,我正在使用这种方法。如果您发现任何其他更方便的方法,请告诉我。