__pthread_kill à la deuxième requête

J'obtiens la réponse de tableau de json d'URL particulière
À la première request, tout fonctionne correctement, mais lorsque la deuxième request est exécutée, l'application se bloque.

libsystem_kernel.dylib`__pthread_kill: 0x1082f885c: déplacer $ 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

Trace de la stack

2015-07-16 13: 44: 37.126 Contact Book [15714: 106637] * Échec de l'assertion dans – [UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-3318/UITableView.m:1582 2015-07-16 13:44 : 37.341 Contact Book [15714: 106637] * Application terminaison due à une exception non interceptée 'NSInternalInconsistencyException', raison: 'Mise à jour invalide: nombre de lignes incorrect dans la section 0. Nombre de lignes contenues dans une section existante après la mise à jour (1) être égal au nombre de lignes contenues dans cette section avant la mise à jour (11), plus ou less le nombre de lignes insérées ou supprimées de cette section (1 inséré, 0 supprimé) et plus ou less le nombre de lignes déplacées vers l'intérieur ou l'extérieur de cette section (0 déplacé, 0 déplacé). ' *** Première stack d'appels: 0 CoreFoundation 0x0000000105cd53f5 exceptionPreprocess + 165 1 libobjc.A.dylib 0x0000000107803bb7 objc_exception_throw + 45 2 CoreFoundation 0x0000000105cd525a + [élévation NSException: format: arguments:] + 106 3 Foundation 0x0000000106c28f – [NSAssertionHandler handleFailureInMethod: object: file: lineNumber: Description:] + 195 4 UIKit 0x000000010663346a – [UITableView _endCellAnimationsWithContext:] + 11746 5 contact livre 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 Réserver 0x0000000105ae6e83 _TTRXFo_iTGSQCSo6NSData_GSQCSo13NSURLRe sponse_GSQCSo7NSError___iT__XFo_oGSQS__oGSQS0__oGSQS1___dT__ + 35 9 Contact Réserver 0x0000000105ae6f0f _TTRXFo_oGSQCSo6NSData_oGSQCSo13NSURLResponse_oGSQCSo7NSError__dT__XFdCb_dGSQS__dGSQS0__dGSQS1___dT__ + 127 10 CFNetwork de 49 – [__ NSCFLocalSessionTask _task_onqueue_didFinish] _block_invoke + 157 11 Fondation 0x000000010618fccf __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK + 7 12 Fondation 0x00000001060cfb32 – [NSBlockOperation principale] + 98 13 Fondation 0x00000001060b2104 – [__ NSOperationInternal _start:] + 645 14 Fondation 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: se termine avec une exception non interceptée de type NSException (lldb)

J'ai le code suivant

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 NSSsortingng if inputText.length > 3 { //TODO repalce space by %20 if flag{ task.cancel()} let url = NSURL(ssortingng: "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 NSSsortingng 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 NSSsortingng 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 } } 

C'est un message d'erreur assez clair, il suffit de le lire. Citation:

Terminaison de l'application due à une exception non interceptée 'NSInternalInconsistencyException', raison: 'Invalid update: nombre de lignes incorrect dans la section 0. Le nombre de lignes contenues dans une section existante après la mise à jour (1) doit être égal au nombre de lignes section avant la mise à jour (11), plus ou less le nombre de lignes insérées ou supprimées de cette section (1 inséré, 0 supprimé) et plus ou less le nombre de lignes déplacées dans ou hors de cette section (0 déplacé, 0 déplacé en dehors).

Ça dit:

  • après la mise à jour (insert / supprimer) vous avez 1 cellule dans la section 0,
  • mais avant de mettre à jour la vue de la table, vous aviez 11 cellules là, alors vous avez inséré 1 cellule, donc il attend 11 + 1 cellules, pas 1

Le problème est que le nombre de cellules dans la section 0 est égal à nameData.count . Et votre code (parties non liées retirées) …

 self.nameData.removeAllObjects() <----- (delete) var tempObject : NSDictionary; for var i=0; i < jsonArray.count; i++ { var jsonDict = jsonArray[i] as NSDictionary var name = jsonDict.valueForKey("name")! as NSSsortingng self.nameData.insertObject(name, atIndex: 0) <----- (insert) let indexPath = NSIndexPath(forRow: 0, inSection: 0) self.tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) <------ (insert) } 

… supprime tous les objects de self.nameData , mais pas de table.

Les cellules de vue de table et votre banque de support ne sont pas synchronisées.

Recharger datatables

Supprimez la ligne self.tableView.insert... et placez self.tableView.reloadData() juste après la boucle for. Il recharge toute la vue de la table.

 self.nameData.removeAllObjects() var tempObject : NSDictionary; for var i=0; i < jsonArray.count; i++ { var jsonDict = jsonArray[i] as NSDictionary var name = jsonDict.valueForKey("name")! as NSSsortingng self.nameData.insertObject(name, atIndex: 0) let indexPath = NSIndexPath(forRow: 0, inSection: 0) } self.tableView.reloadData() 

Ou rechargez juste une section.

 func reloadSections(_ sections: NSIndexSet) 

Supprimer les éléments et insert

Si vous ne souhaitez pas recharger toutes les cellules (vue de table entière), vous devez garder à l'esprit que votre magasin de sauvegarde des données doit être synchronisé avec la vue de table. En d'autres termes, si vous supprimez une cellule de la vue tableau, vous devez la supprimer de votre magasin de sauvegarde. Si vous insérez une cellule dans la vue tableau, vous devez l'insert dans le magasin de sauvegarde. Et vice versa.

Dans votre cas, vous appelez self.nameData.removeAllObjects() , mais vous n'avez pas supprimé les cellules de vue de table pour ces objects. Tu devrais appeler …

 func deleteItemsAtIndexPaths(_ indexPaths: [NSIndexPath]) 

… sur self.tableView pour tous les objects que vous avez supprimés de self.nameData .

Si vous faites beaucoup d' deleteItems.../insertItems/... , il est bon de les performBatchUpdates(_:completion:) dans performBatchUpdates(_:completion:) :

 func performBatchUpdates(_ updates: (() -> Void)?, completion completion: ((Bool) -> Void)?) 

Anime plusieurs opérations d'insertion, de suppression, de rechargement et de déplacement en tant que groupe.