__pthread_kill上第二请求(__pthread_kill on second reque

2019-10-23 21:59发布

我正在从特定的URL JSON阵列响应
在第一次请求每一件事工作正常,但是当第二个请求,然后应用程序崩溃。

libsystem_kernel.dylib`__pthread_kill:0x1082f885c:MOVL $ 0x2000148,%eax中0x1082f8861:MOVQ%RCX,R10%0x1082f8864:系统调用0x1082f8866:宰0x1082f8870; __pthread_kill + 20 0x1082f8868:MOVQ%RAX,%RDI 0x1082f886b:JMP 0x1082f5175; cerror_nocancel 0x1082f8870:retq
0x1082f8871:NOP
0x1082f8872:NOP
0x1082f8873:NOP



堆栈跟踪

2015年7月16日13:44:37.126联系簿[15714:106637] *在声明失败- [UITableView的_endCellAnimationsWithContext:],2015年7月16日/SourceCache/UIKit_Sim/UIKit-3318/UITableView.m:1582 13时44分:37.341通讯录[15714:106637] *终止应用程序由于未捕获的异常“NSInternalInconsistencyException”,原因:“无效更新:在部分0的行的无效数更新后包含在现有段的行数(1)必须等于包含在更新(11)之前部的行数,加或减插入或从该部分(1插入时,0删除)和正或负的行数被删除的行的数量移入或移出该节(0移动中,0移出)。” ***第一掷调用堆栈:(0的CoreFoundation 0x0000000105cd53f5 exceptionPreprocess + 165 1周libobjc.A.dylib 0x0000000107803bb7 objc_exception_throw + 45 2的CoreFoundation 0x0000000105cd525a + [NSException提高:格式:参数:] + 106 3基金会0x000000010616c28f - [NSAssertionHandler handleFailureInMethod:对象:文件:LINENUMBER:描述:] + 195 4的UIKit 0x000000010663346a - [UITableView的_endCellAnimationsWithContext:] + 11746 5联系簿0x0000000105ae6a11 _TFFC12Contact_Book20MasterViewController38updateSearchResultsForSearchControllerFS0_FCSo18UISearchControllerT_U_FTGSQCSo6NSData_GSQCSo13NSURLResponse_GSQCSo7NSError__T_ + 2625 6联系簿0x0000000105ae6bb3 _TTRXFo_oGSQCSo6NSData_oGSQCSo13NSURLResponse_oGSQCSo7NSError__dT__XFo_iTGSQS__GSQS0__GSQS1____iT + 51 7联系簿0x0000000105ae4091 _TPA__TTRXFo_oGSQCSo6NSData_oGSQCSo13NSURLResponse_oGSQCSo7NSError__dT__XFo_iTGSQS__GSQS0__GSQS1____iT__ + 81 8联系簿0x0000000105ae6e83 _TTRXFo_iTGSQCSo6NSData_GSQCSo13NSURLRe sponse_GSQCSo7NSError___iT__XFo_oGSQS__oGSQS0__oGSQS1___dT__ + 35 9联络簿0x0000000105ae6f0f _TTRXFo_oGSQCSo6NSData_oGSQCSo13NSURLResponse_oGSQCSo7NSError__dT__XFdCb_dGSQS__dGSQS0__dGSQS1___dT__ + 127 10 CFNetwork的0x0000000108aaebbb 49 - [__ NSCFLocalSessionTask _task_onqueue_didFinish] _block_invoke + 157 11基金会0x000000010618fccf __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK + 7 12基金会0x00000001060cfb32 - [NSBlockOperation主] + 98 13基金会0x00000001060b2104 - [__ NSOperationInternal _start:] + 645 14基础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:与类型NSException的未捕获的异常(LLDB终止)

我有以下代码

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
}
}

Answer 1:

It's pretty clear error message, just read it. Quote:

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).

It says:

  • after the update (insert/delete) you've got 1 cell in section 0,
  • but before you did update the table view, you had 11 cells there, then you did insert 1 cell, thus it expects 11+1 cells, not 1

Problem is that number of cells in section 0 equals to nameData.count. And your code (removed unrelated parts) ...

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 NSString
  self.nameData.insertObject(name, atIndex: 0) <----- (insert)
  let indexPath = NSIndexPath(forRow: 0, inSection: 0)
  self.tableView.insertRowsAtIndexPaths([indexPath],
    withRowAnimation: .Fade)  <------ (insert)
}

... 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 place self.tableView.reloadData() just after the for loop. It reloads the whole table view.

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 NSString
  self.nameData.insertObject(name, atIndex: 0)
  let indexPath = NSIndexPath(forRow: 0, inSection: 0)
}
self.tableView.reloadData()

Or reload just one section.

func reloadSections(_ sections: NSIndexSet)

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 ...

func deleteItemsAtIndexPaths(_ indexPaths: [NSIndexPath])

... on self.tableView for all objects you did remove from self.nameData.

If you do lot of deleteItems.../insertItems/... calls, it's good to wrap them in performBatchUpdates(_:completion:):

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

Animates multiple insert, delete, reload, and move operations as a group.



文章来源: __pthread_kill on second request