__pthread_kill第二次请求

时间:2015-07-16 08:33:20

标签: ios swift uitableview uisearchbar

我从特定网址获取json数组响应 在第一次请求时,每个东西都工作正常,但是当第二个请求进入时,应用程序崩溃。

  

libsystem_kernel.dylib`__pthread_kill:   0x1082f885c:movl $ 0x2000148,%eax   0x1082f8861:movq%rcx,%r10   0x1082f8864:系统调用   0x1082f8866:jae 0x1082f8870; __pthread_kill + 20   0x1082f8868:movq%rax,%rdi   0x1082f886b:jmp 0x1082f5175; cerror_nocancel   0x1082f8870:retq
  0x1082f8871:nop
  0x1082f8872:nop
  0x1082f8873:nop



栈跟踪

  

2015-07-16 13:44:37.126联系簿[15714:106637] *断言失败 - [UITableView _endCellAnimationsWithContext:],/ SourceCache / UIKit_Sim / UIKit-3318 / UITableView.m:1582   2015-07-16 13:44:37.341联系簿[15714:106637] * 由于未捕获的异常终止应用程序' NSInternalInconsistencyException',原因:'无效更新:无效行数更新后的现有部分中包含的行数(1)必须等于更新前该部分中包含的行数(11),加上或减去从中插入或删除的行数部分(插入1个,删除0个)并加上或减去移入或移出该部分的行数(0移入,0移出)。'   ***第一次抛出调用堆栈:   (       0 CoreFoundation 0x0000000105cd53f5 exceptionPreprocess + 165       1 libobjc.A.dylib 0x0000000107803bb7 objc_exception_throw + 45       2 CoreFoundation 0x0000000105cd525a + [NSException raise:format:arguments:] + 106       3基金会0x000000010616c28f - [NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 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_GSQCSo13NSURLResponse_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 main] + 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
}
}

1 个答案:

答案 0 :(得分:2)

这是非常明确的错误信息,只需阅读即可。引用:

  

由于未捕获的异常而终止应用   &#39; NSInternalInconsistencyException&#39;,原因:&#39;无效更新:无效   第0节中的行数。包含在中的行数   更新后的现有部分(1)必须等于数量   更新前的该部分中包含的行(11),加号或减号   从该部分插入或删除的行数(插入1个,   删除0)加上或减去移入或移出的行数   该部分(0移入,0移出)。

它说:

  • 更新(插入/删除)后,您在第0部分中有1个单元格,
  • 但在你更新表格视图之前,你有11个单元格,然后你插入了1个单元格,因此它需要11 + 1个单元格,而不是1个

问题是0部分中的单元格数量等于nameData.count。和你的代码(删除不相关的部分)......

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

...从self.nameData删除所有对象,但不从表视图中删除。

表视图单元格和后备存储区未同步。

重新加载数据

删除self.tableView.insert...行,并在for循环后放置self.tableView.reloadData()。它重新加载整个表视图。

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

或只重新加载一个部分。

func reloadSections(_ sections: NSIndexSet)

删除项目&amp;然后插入

如果您不想重新加载所有单元格(整个表视图),则必须记住,数据的后备存储必须与表视图保持同步。换句话说 - 如果从表视图中删除单元格,则必须将其从后备存储中删除。如果确实将单元格插入表视图,则必须将其插入到后备存储中。反之亦然。

在您的情况下,您致电self.nameData.removeAllObjects(),但没有删除这些对象的表格视图单元格。你应该打电话给...

func deleteItemsAtIndexPaths(_ indexPaths: [NSIndexPath])
对于您从self.tableView删除的所有对象,

... self.nameData

如果你进行了很多deleteItems.../insertItems/...次来电话,最好将它们包裹在performBatchUpdates(_:completion:)中:

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

将多个插入,删除,重新加载和移动操作设置为一组动画。