崩溃问题 attempt to delete item which only contains items before the update

代码:

let newInsertItemIdx:Int = 0

let firstItemIndexPath:NSIndexPath = NSIndexPath(forRow: newInsertItemIdx, inSection: 0)

self.tableView.reloadRowsAtIndexPaths([firstItemIndexPath], withRowAnimation: UITableViewRowAnimation.Automatic)

出错:

2015-12-02 15:28:37.409 JianDao[18264:1143873] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3512.29.5/UITableView.m:1426

2015-12-02 15:28:44.998 JianDao[18264:1143873] *** Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘attempt to delete row 0 from section 0 which only contains 0 rows before the update’

*** First throw call stack:

(

    0   CoreFoundation                      0x0000000110a65f45 __exceptionPreprocess + 165

    1   libobjc.A.dylib                     0x000000010fcfedeb objc_exception_throw + 48

    2   CoreFoundation                      0x0000000110a65daa +[NSException raise:format:arguments:] + 106

    3   Foundation                          0x000000010f94b5ee -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 198

    4   UIKit                               0x000000011169b19b -[UITableView _endCellAnimationsWithContext:] + 4799

    5   JianDao                             0x000000010f3ae3d3 _TFFC7JianDao26ConversationViewController22addNewConversationItemFS0_FCS_16ConversationItemT_U_FT_T_ + 675

    6   JianDao                             0x000000010f389bd7 _TTRXFo__dT__XFdCb__dT__ + 39

    7   libdispatch.dylib                   0x00000001133dce5d _dispatch_call_block_and_release + 12

    8   libdispatch.dylib                   0x00000001133fd49b _dispatch_client_callout + 8

    9   libdispatch.dylib                   0x00000001133e52af _dispatch_main_queue_callback_4CF + 1738

    10  CoreFoundation                      0x00000001109c62e9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9

    11  CoreFoundation                      0x00000001109878a9 __CFRunLoopRun + 2073

    12  CoreFoundation                      0x0000000110986e08 CFRunLoopRunSpecific + 488

    13  GraphicsServices                    0x0000000115106ad2 GSEventRunModal + 161

    14  UIKit                               0x000000011157530d UIApplicationMain + 171

    15  JianDao                             0x000000010f355f2d main + 109

    16  libdyld.dylib                       0x000000011343192d start + 1

    17  ???                                 0x0000000000000001 0x0 + 1

)

libc++abi.dylib: terminating with uncaught exception of type NSException

objective c – NSInternalInconsistencyException’, reason: ‘attempt to insert row 0 into section 0, but there are only 0 rows in section 0 after the update’ – Stack Overflow

iphone – Crash on reloadRowsAtIndexPath but not on reloadData – Stack Overflow

ios – "Attempt to insert row 0 into section 0, but there are only 0 rows in section 0 after the update" Error – Stack Overflow

Reloading the Table View – UITableView Class Reference

reloadData()

Reloads the rows and sections of the table view.

Declaration

SWIFT

func reloadData()

Discussion

Call this method to reload all the data that is used to construct the table, including cells, section headers and footers, index arrays, and so on. For efficiency, the table view redisplays only those rows that are visible. It adjusts offsets if the table shrinks as a result of the reload. The table view’s delegate or data source calls this method when it wants the table view to completely reload its data. It should not be called in the methods that insert or delete rows, especially within an animation block implemented with calls tobeginUpdatesandendUpdates.

感觉是:

应该把此处的:

reloadRowsAtIndexPaths

换成

reloadData

-》因为此处是datasource中的data变化了。

-》所以不应该调用reloadRowsAtIndexPaths,而应该直接用reloadData???

-》但是不会导致效率很低吗?

有点看懂了:

此处是:

对于tableView的datasource的数组:

conversationItemList

最开始conversationItemList是空的,count是0

此处之前已经调用了:

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

 print("ConversationViewController numberOfRowsInSection")

 return conversationItemList.count

    }

所以当时是numberOfRowsInSection返回的是0

而此处虽然是已经添加数据了:

        if conversationItemList.count == 0 {

 conversationItemList.append(newConversationItem)

}

 else {

 conversationItemList.insert(newConversationItem, atIndex: newInsertItemIdx)

        }

但是此时tableView并不知道你的数据源变化了

-》所以此时调用reloadRowsAtIndexPaths,发现:

section 0中,并没有数据

而reload需要

先删除delete

再添加add

所以此时delete不存在的row的话,就报错了。

-》所以,此处应该是先调用reloadData

-》让系统知道数据变化了。

iphone – Crash on reloadRowsAtIndexPath but not on reloadData – Stack Overflow

中的解释,也和我猜的一样:

“I know that it has been a while since this question was asked but I think the problem might be that, reloadRowsAtIndexPaths relies on the prior existence of those rows in the table and internally deletes, recreates and inserts them back in (under the hood). So when you are calling the specific reload without those rows already being in the table, it is trying to delete a row that is not there.

I came across the same problem with a collection view. The reason why a full reload works is because it refreshes the whole thing and does not rely on prior state, only on the current condition of your data source.

This is my take on the problem.”

[总结]

所以结论很简单:

当你之前的对应的row中的cell并存在的话

(注意:即使你数据源中的list中已经刚(通过insert或append)添加了对应的数据,但是却没有调用reloadData的话,对应的UI界面中的UITableViewCell还是不存在的)

则此时调用reloadRowsAtIndexPaths,就会出错:

因为:

reloadRowsAtIndexPaths是依赖于之前的状态的

之前的状态是还不存在对应的UITableViewCell

reloadRowsAtIndexPaths需要先去delete对应的cell,然后再去重新添加对应的cell的

解决办法是:

在添加了数据源中对应的行的数据后,先去调用reloadData

(其实也就不需要:再去调用reloadRowsAtIndexPaths)了。。。


转载自:https://www.crifan.com/swift_has_update_datasource_but_reloadrowsatindexpaths_still_attempt_to_delete_row_0_from_section_0/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容