My ReloadData call is taking over 40 seconds between the actual ReloadData call and the first time the cellForRowAtIndexPath function of the tableview is called. Does anyone know why there is such a performance hit?
here is code for your reference: This code is called after my webAPI data has been returned and completely loaded into the appropriate local objects.
func reloadPage()
{
btnMenu.hidden = false
btnMapAll.hidden = false
if ApplicationMode != AppMode.Normal
{
btnUseGPS.hidden = false
}
else
{
btnUseGPS.hidden = true
}
StartTime = CACurrentMediaTime()
self.NearbyLocationsTable.reloadData()
}
Here is my cellForRowAtIndexPath function. You can see I print the time at the very beginning of the first time the function is called.
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!
}
The information that is printed is as follows: cellForRowAtIndexPath Time Elapsed Optional("40.0729780000402")
Sometimes the time elapsed is as low as 12 seconds but that is still way too long. Any idea what is causing this?
I do implement the numberOfRowsInSection function. this executes within a few milliseconds after call reloadData. I also implement the willDisplayCell function but that is only ever called after the cellForRowAtIndexPath (i.e. after the 40 seconds have elapsed).
An ideas or suggestions would be greatly appreciated.
Here is the other code:
Protocol / Delegate Definition:
protocol LocationAPICallDelegate
{
func LocationAPIComplete()
}
ViewModel Code:
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()
}
You can see the delegate is called in the ViewController code that is below.
class NearbyLocationsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, LocationAPICallDelegate, DOWAPICallDelegate, SideBarDelegate, GPSLocationDelegate
Then I declare an instance of the ViewModel class
let iobj_NearbyLocationsVM: NearbyLocationsViewModel = NearbyLocationsViewModel()
Then in the viewDidLoad I set the delegate of the ViewModel to self as follows:
iobj_NearbyLocationsVM.iobj_LocationAPICompleteDelegate = self
Then the delegate function is called when the data is all loaded in the ViewModel using the following which call the ReloadPage
func LocationAPIComplete()
{
reloadPage()
}
If anyone would like to see any other code please let me know. Thanks in advance for any assistance.
So I did some investigating on milo526's answer and found that changing the call to my delegate as follows appears to have solved the problem.
//Switch back to main thread
dispatch_async(dispatch_get_main_queue()) { ()
self.iobj_LocationAPICompleteDelegate?.LocationAPIComplete()
}
I guess my big comment / statement now is -- no one should ever post examples of using NSURLSession.sharedSession() with dataTaskWithURL without addressing the thread switching needed in the closure. :)