iOS swift UITableView ReloadData 性能
Posted
技术标签:
【中文标题】iOS swift UITableView ReloadData 性能【英文标题】:iOS swift UITableView ReloadData performance 【发布时间】:2015-04-19 19:17:02 【问题描述】:我的 ReloadData 调用在实际 ReloadData 调用和第一次调用 tableview 的 cellForRowAtIndexPath 函数之间花费了 40 多秒。有谁知道为什么会有这样的性能下降?
这是供您参考的代码: 在我的 webAPI 数据返回并完全加载到适当的本地对象后调用此代码。
func reloadPage()
btnMenu.hidden = false
btnMapAll.hidden = false
if ApplicationMode != AppMode.Normal
btnUseGPS.hidden = false
else
btnUseGPS.hidden = true
StartTime = CACurrentMediaTime()
self.NearbyLocationsTable.reloadData()
这是我的 cellForRowAtIndexPath 函数。您可以看到我在第一次调用该函数时打印了时间。
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
if EndTime == nil
EndTime = CACurrentMediaTime() - StartTime!
println("cellForRowAtIndexPath Time Elapsed \(EndTime?.description)")
var lobj_NearbyLocationEntry: NearbyLocationsCell? = tableView.dequeueReusableCellWithIdentifier(lc_LocationCellTableIdentifier) as? NearbyLocationsCell
if(lobj_NearbyLocationEntry == nil)
lobj_NearbyLocationEntry = NearbyLocationsCell(style: UITableViewCellStyle.Default, reuseIdentifier: lc_LocationCellTableIdentifier)
lobj_NearbyLocationEntry!.ConfigureCell(gobj_NearbyLocations[indexPath.row].Title, pd_Rating: gobj_NearbyLocations[indexPath.row].Rating, ps_Distance: gobj_NearbyLocations[indexPath.row].Distance, ps_Attributes: gobj_NearbyLocations[indexPath.row].AttributesTexts, pi_RowIndex: indexPath.row)
return lobj_NearbyLocationEntry!
打印出来的信息如下: cellForRowAtIndexPath Time Elapsed Optional("40.0729780000402")
有时经过的时间低至 12 秒,但这仍然太长了。知道是什么原因造成的吗?
我确实实现了 numberOfRowsInSection 函数。这在调用 reloadData 后的几毫秒内执行。我还实现了 willDisplayCell 函数,但它只在 cellForRowAtIndexPath 之后调用(即在 40 秒过去之后)。
非常感谢您提出想法或建议。
这是另一个代码:
协议/委托定义:
protocol LocationAPICallDelegate
func LocationAPIComplete()
ViewModel 代码:
var iobj_LocationAPICompleteDelegate: LocationAPICallDelegate?
func NearbyLocationsGet(ps_Langauge: String, pi_Day_Of_Week: Int, pd_Latitude: Double, pd_Longitude: Double, pl_CityID: Int, pi_Distance: Int, pb_Rating_For_Men: Bool, pi_NumberOfEntries: Int, pb_Location_In_Metric: Bool)
var ls_CompleteURL: String = ""
var ls_NSURL: NSURL
ls_CompleteURL = BuildURL(ps_Langauge, pi_Day_Of_Week: pi_Day_Of_Week, pd_Latitude: pd_Latitude, pd_Longitude: pd_Longitude, pl_CityID: pl_CityID, pi_Distance: pi_Distance, pb_Rating_For_Men: pb_Rating_For_Men, pi_NumberOfEntries: pi_NumberOfEntries, pb_Location_In_Metric: pb_Location_In_Metric)
var request : NSMutableURLRequest = NSMutableURLRequest()
ls_NSURL = NSURL(string: ls_CompleteURL)!
let urlSession = NSURLSession.sharedSession()
let jsonQuery = urlSession.dataTaskWithURL(ls_NSURL, completionHandler: data, response, error -> Void in
if (error != nil)
println(error.localizedDescription)
var err: NSError?
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as
[[String:AnyObject]]
if (err != nil)
println("JSON Error \(err!.localizedDescription)")
else
self.LoadJSONLocationDataToObjects(jsonResult)
self.iobj_LocationAPICompleteDelegate?.LocationAPIComplete()
)
jsonQuery.resume()
您可以在下面的 ViewController 代码中看到委托被调用。
class NearbyLocationsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, LocationAPICallDelegate, DOWAPICallDelegate, SideBarDelegate, GPSLocationDelegate
然后我声明一个 ViewModel 类的实例
let iobj_NearbyLocationsVM: NearbyLocationsViewModel = NearbyLocationsViewModel()
然后在 viewDidLoad 我将 ViewModel 的委托设置为 self 如下:
iobj_NearbyLocationsVM.iobj_LocationAPICompleteDelegate = self
然后当数据全部加载到 ViewModel 中时调用委托函数,使用以下调用 ReloadPage 的方法
func LocationAPIComplete()
reloadPage()
如果有人想查看任何其他代码,请告诉我。提前感谢您的任何帮助。
【问题讨论】:
您声明您正在从 API 加载数据,您是否在数据调用的完成处理程序中编辑 UI?如果你这样做,你deck
主线程吗?
我在 ViewModel 类中使用委托,并在数据全部下载并加载到对象中时调用委托的方法。该委托是调用重新加载页面功能的地方。因此,据我所知,这一切都在主线程上运行。我已经用我的 api 调用和委托代码更新了这个问题,以防我遗漏了什么。
在你调用附近LocationGet中的委托函数之前尝试去主线程队列
我不明白你在调用 nearLocationGet 中的委托函数之前先装到主线程是什么意思。你能提供一个例子来指向它的文档吗?
【参考方案1】:
所以我对 milo526 的回答进行了一些调查,发现如下更改对我的代表的调用似乎已经解决了问题。
//Switch back to main thread
dispatch_async(dispatch_get_main_queue()) ()
self.iobj_LocationAPICompleteDelegate?.LocationAPIComplete()
我想我现在的重要评论/声明是——没有人应该发布使用 NSURLSession.sharedSession() 和 dataTaskWithURL 的示例,而不解决闭包中所需的线程切换。 :)
【讨论】:
以上是关于iOS swift UITableView ReloadData 性能的主要内容,如果未能解决你的问题,请参考以下文章