最新消息:20181230 VPS服务器已从Linode换到腾讯云香港,主题仍用朋友推荐的大前端D8

[已解决]swift中UITableView添加新的行并且确保不会崩溃出错

Swift crifan 904浏览 0评论

uitableview add new row

swift uitableview add new row

ios uitableview add new row

Insert Table Row | Ryan Wright

ios – How to add item to UITableView? – Stack Overflow

好像主要的还是:

  tableView.beginUpdates()
  tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Bottom)
  tableView.endUpdates()

然后,到时候记得去:

给自己的函数insertMessageAndScroll去添加lock

self.insertLock.lock()
        //insert row
        dispatch_async(dispatch_get_main_queue(), { () -> Void in
                let insertedRowIndexPath:NSIndexPath = NSIndexPath(forRow: insertedRowIdx, inSection: 0)
               
                msgTVC.messageTableView.beginUpdates()
                msgTVC.messageTableView.insertRowsAtIndexPaths([insertedRowIndexPath], withRowAnimation: UITableViewRowAnimation.Bottom)
                msgTVC.messageTableView.endUpdates()
        })

但是还是不行。

换成reload,结果还是出错

        //insert row
        dispatch_async(dispatch_get_main_queue(), { () -> Void in
            //not reload for only 1 row
            if insertedRowIdx > 0 {
                let insertedRowIndexPath:NSIndexPath = NSIndexPath(forRow: insertedRowIdx, inSection: 0)
               
                msgTVC.messageTableView.beginUpdates()
                //            msgTVC.messageTableView.insertRowsAtIndexPaths([insertedRowIndexPath], withRowAnimation: UITableViewRowAnimation.Bottom)
                msgTVC.messageTableView.reloadRowsAtIndexPaths([insertedRowIndexPath], withRowAnimation: UITableViewRowAnimation.Bottom)
                msgTVC.messageTableView.endUpdates()
            }
        })

insertrowsatindexpaths crash

ios – How to protect tableview from crashing during insertRowsAtIndexPaths and device rotation – Stack Overflow

->

还是之前的问题:

要确保:

insert data

insert row(insertRowsAtIndexPaths)

不仅保持数量上的一致

还要确保在同一个线程,即insertRowsAtIndexPaths所要求的主线程中

这样才不会出现:

insertRowsAtIndexPaths时,在其他线程中,其实已经改变了dataList了。。

-》导致data和row不一致,导致出错

[总结]

最后用代码:

        //method 1: insert data and reloadData, and scroll
        dispatch_async(dispatch_get_main_queue(), { () -> Void in
            //insert to correct position according datetime
            var insertedRowIdx:Int = 0
            var hasInserted:Bool = false
            for (curIdx, curMessage) in msgTVC.messageList.enumerate() {
    //            print("[\(curIdx)] newMessage.timestamp=\(newMessage.timestamp), curMessage.timestamp=\(curMessage.timestamp), newMessage.text=\(newMessage.text)")
                if newMessage.timestamp < curMessage.timestamp {
                    msgTVC.messageList.insert(newMessage, atIndex: curIdx)
                    insertedRowIdx = curIdx
                    hasInserted = true
                    break
                }
            }
           
            if !hasInserted {
                msgTVC.messageList.append(newMessage)
                insertedRowIdx = msgTVC.messageList.count 1
                hasInserted = true
            }
           
            //update timestamp string
            if insertedRowIdx > 0 {
                let prevMessage = msgTVC.messageList[insertedRowIdx – 1]
                newMessage.timestampStr = generateTimestampStr(newMessage.timestamp, prevTimestamp: prevMessage.timestamp)
            } else {
                newMessage.timestampStr = generateTimestampStr(newMessage.timestamp, prevTimestamp: nil)
            }
    //        print("insertedRowIdx=\(insertedRowIdx)")
            //insert row
            let insertedRowIndexPath:NSIndexPath = NSIndexPath(forRow: insertedRowIdx, inSection: 0)
            msgTVC.messageTableView.beginUpdates()
            msgTVC.messageTableView.insertRowsAtIndexPaths([insertedRowIndexPath], withRowAnimation: UITableViewRowAnimation.Bottom)
            msgTVC.messageTableView.endUpdates()
           
            if isCurrentShowingVc(msgTVC) {
                //only when current vc, then scroll to that row
                msgTVC.messageTableView.scrollToRowAtIndexPath(insertedRowIndexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: true)
            }
        })

确保了:

先去更新数据:

messageList.insert或messageList.append

紧接着,在同一线程中,去插入行:

messageTableView.insertRowsAtIndexPaths

注:

此处的同一个线程,意味着:都在主线程dispatch_get_main_queue

因为insertRowsAtIndexPaths要求必须处于主线程

转载请注明:在路上 » [已解决]swift中UITableView添加新的行并且确保不会崩溃出错

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
63 queries in 0.098 seconds, using 9.74MB memory