I am getting json array response from particular url
On first request every thing is working fine but when second request goes then application crashes.
libsystem_kernel.dylib`__pthread_kill: 0x1082f885c: movl $0x2000148, %eax 0x1082f8861: movq %rcx, %r10 0x1082f8864: syscall 0x1082f8866: jae 0x1082f8870 ; __pthread_kill + 20 0x1082f8868: movq %rax, %rdi 0x1082f886b: jmp 0x1082f5175 ; cerror_nocancel 0x1082f8870: retq
0x1082f8871: nop
0x1082f8872: nop
0x1082f8873: nop
StackTrace
2015-07-16 13:44:37.126 Contact Book[15714:106637] * Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-3318/UITableView.m:1582 2015-07-16 13:44:37.341 Contact Book[15714:106637] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (11), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).' *** First throw call stack: ( 0 CoreFoundation 0x0000000105cd53f5 exceptionPreprocess + 165 1 libobjc.A.dylib 0x0000000107803bb7 objc_exception_throw + 45 2 CoreFoundation 0x0000000105cd525a +[NSException raise:format:arguments:] + 106 3 Foundation 0x000000010616c28f -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195 4 UIKit 0x000000010663346a -[UITableView _endCellAnimationsWithContext:] + 11746 5 Contact Book 0x0000000105ae6a11 _TFFC12Contact_Book20MasterViewController38updateSearchResultsForSearchControllerFS0_FCSo18UISearchControllerT_U_FTGSQCSo6NSData_GSQCSo13NSURLResponse_GSQCSo7NSError__T_ + 2625 6 Contact Book 0x0000000105ae6bb3 _TTRXFo_oGSQCSo6NSData_oGSQCSo13NSURLResponse_oGSQCSo7NSError__dT__XFo_iTGSQS__GSQS0__GSQS1____iT + 51 7 Contact Book 0x0000000105ae4091 _TPA__TTRXFo_oGSQCSo6NSData_oGSQCSo13NSURLResponse_oGSQCSo7NSError__dT__XFo_iTGSQS__GSQS0__GSQS1____iT__ + 81 8 Contact Book 0x0000000105ae6e83 _TTRXFo_iTGSQCSo6NSData_GSQCSo13NSURLResponse_GSQCSo7NSError___iT__XFo_oGSQS__oGSQS0__oGSQS1___dT__ + 35 9 Contact Book 0x0000000105ae6f0f _TTRXFo_oGSQCSo6NSData_oGSQCSo13NSURLResponse_oGSQCSo7NSError__dT__XFdCb_dGSQS__dGSQS0__dGSQS1___dT__ + 127 10 CFNetwork 0x0000000108aaebbb 49-[__NSCFLocalSessionTask _task_onqueue_didFinish]_block_invoke + 157 11 Foundation 0x000000010618fccf __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK + 7 12 Foundation 0x00000001060cfb32 -[NSBlockOperation main] + 98 13 Foundation 0x00000001060b2104 -[__NSOperationInternal _start:] + 645 14 Foundation 0x00000001060b1d13 __NSOQSchedule_f + 184 15 libdispatch.dylib 0x0000000107fa87f4 _dispatch_client_callout + 8 16 libdispatch.dylib 0x0000000107f90bf4 _dispatch_queue_drain + 1417 17 libdispatch.dylib 0x0000000107f90506 _dispatch_queue_invoke + 235 18 libdispatch.dylib 0x0000000107f92ff7 _dispatch_root_queue_drain + 682 19 libdispatch.dylib 0x0000000107f9463c _dispatch_worker_thread2 + 52 20 libsystem_pthread.dylib 0x000000010833eef8 _pthread_wqthread + 314 21 libsystem_pthread.dylib 0x0000000108341fb9 start_wqthread + 13 ) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)
I have following code
import UIKit
class MasterViewController: UITableViewController, UISearchControllerDelegate, UISearchResultsUpdating, UISearchBarDelegate {
var completeData = NSMutableArray()
var nameData = NSMutableArray()
override func awakeFromNib() {
super.awakeFromNib()
}
var searchController : UISearchController!
override func viewDidLoad() {
super.viewDidLoad()
self.searchController = UISearchController(searchResultsController: nil)
self.searchController.searchResultsUpdater = self
self.searchController.delegate = self
self.searchController.searchBar.delegate = self
self.searchController.hidesNavigationBarDuringPresentation = false
self.searchController.dimsBackgroundDuringPresentation = true
self.navigationItem.titleView = searchController.searchBar
self.definesPresentationContext = true
}
var flag = false
var task: NSURLSessionTask!
func updateSearchResultsForSearchController(searchController: UISearchController) {
var inputText = searchController.searchBar.text as NSString
if inputText.length > 3 {
//TODO repalce space by %20
if flag{
task.cancel()}
let url = NSURL(string: "http://172.26.1.39:8080/ContactBook/search?term="+inputText);
task = NSURLSession.sharedSession().dataTaskWithURL(url){(data, response, error) in
if(error != nil){
println("SOME ERROR")
return
}
var parseError: NSError?
var jsonArray = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments, error: &parseError) as NSArray
if parseError != nil {
println("something wrong")
return
}
self.completeData.removeAllObjects()
self.nameData.removeAllObjects()
var tempObject : NSDictionary;
for var i=0; i < jsonArray.count; i++ {
var jsonDict = jsonArray[i] as NSDictionary
self.completeData.insertObject(jsonDict, atIndex: 0)
var name = jsonDict.valueForKey("name")! as NSString
self.nameData.insertObject(name, atIndex: 0)
let indexPath = NSIndexPath(forRow: 0, inSection: 0)
self.tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
}
flag = true
task.resume()
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Segues
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showDetail" {
if let indexPath = self.tableView.indexPathForSelectedRow() {
let object = completeData[indexPath.row] as NSDictionary
(segue.destinationViewController as DetailViewController).detailItem = object
}
}
}
// MARK: - Table View
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return nameData.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
let object = nameData[indexPath.row] as NSString
cell.textLabel?.text = object.description
return cell
}
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return false
}
}
It's pretty clear error message, just read it. Quote:
It says:
Problem is that number of cells in section
0
equals tonameData.count
. And your code (removed unrelated parts) ...... removes all objects from
self.nameData
, but not from table view.Table view cells and your backing store is not synced.
Reload Data
Remove
self.tableView.insert...
line and placeself.tableView.reloadData()
just after the for loop. It reloads the whole table view.Or reload just one section.
Delete Items & Then Insert
If you do not want to reload all cells (whole table view), you must keep in mind that your backing store for data must be kept in sync with table view. In other words - if you do remove cell from table view, you must remove it from your backing store. If you do insert cell into table view, you must insert it into backing store. And vice versa.
In your case, you call
self.nameData.removeAllObjects()
, but you didn't delete table view cells for these objects. You should call ...... on
self.tableView
for all objects you did remove fromself.nameData
.If you do lot of
deleteItems.../insertItems/...
calls, it's good to wrap them inperformBatchUpdates(_:completion:)
: