Asyncdisplaykit: [ASCollectionView] Looking for debugging tips on a data source inconsistency.

Created on 10 Oct 2016  Â·  4Comments  Â·  Source: facebookarchive/AsyncDisplayKit

Hello again guys, and thank you for this wonderful framework!

screen shot 2016-10-10 at 20 01 24

From time to time I face this crash in my app.
I use Realm and Realm notifications to make tableView updates. So, in some situations I need to work with database from multiple threads. And sometimes "beginUpdates" starts when other update in progress... In some situations it works OK, but sometimes it crashes.

I made this crazy stress test to reproduce it quickly (yes, I know - writing to DB from other threads is evil, but many people do it in their apps).

At this moment, to avoid this crash, I use NSMutableArray-category with swizzled methods "removeObjectsAtIndexes:" and some others with try:catch: wrapper, but it so dirty =(
So, can we somehow avoid this crash without dirty methods like swizzling?

Sample project here

Community Debugging

All 4 comments

@stephenkopylov Hi Stephen! I'd be glad to look into this for you – sorry for delay in responding – but the sample project says "File is deleted."

What version/commit hash of ASDK are you targeting? In most recent versions (since 1.9.8 I believe) ASDK will throw exceptions if your data source becomes inconsistent with the table view, which looks like happened in this case.

Would appreciate an update and we'll look into this.

@Adlai-Holler sample project was reuploaded.
Please, check it again.

@stephenkopylov Hi there - I just installed your sample project locally (thanks for creating one!) and ran it with the latest version of ASDK.

It does appear that the app code is submitting invalid update details to AsyncDisplayKit. You should also get an internal inconsistency error if you linked it up with UICollectionView.

I think there could be a thread safety issue in the TableViewController in the sample app. Somehow, the data source (self.results) is ending up with fewer items than the insertions / deletions have reported. In other words, items are getting removed from .results at some point, without the table being told they were inserted or deleted.

Here's the log of my debug session. Please do reopen this task or come find us on Slack if you encounter any behavior from ASDK that looks incorrect! If you could tweak your sample project so a #define swaps in a UICollectionView for the ASCollectionView, that could also help isolate the issue.

"2016-10-31 18:20:58.313 ASTableViewUpdatesSample[82747:1554244] Invalid number of items in section 0. The number of items after the update (29) must be equal to the number of items before the update (176) plus or minus the number of items inserted or deleted (29 inserted, 0 deleted).
2016-10-31 18:20:58.314 ASTableViewUpdatesSample[82747:1554244] *** Assertion failure in -[_ASHierarchyChangeSet _validateUpdate], /Users/scottg/Downloads/ASTableViewUpdatesSample/Pods/AsyncDisplayKit/AsyncDisplayKit/Private/_ASHierarchyChangeSet.mm:481
(lldb) po change

(lldb) p change insertionsInSection:0 $1 = 0x000061800005a880 @"29 elements"
(lldb) p change deletionsInSection:0 $2 = 0x00006180004451c0 @"0 elements"
(lldb) po strongSelf.results
RLMResults <0x7ff7d6401040> (
[0] TestModel {
objectId = 0;
},
[1] TestModel {
objectId = 1;
},
[2] TestModel {
objectId = 2;
},
[3] TestModel {
objectId = 3;
},
[4] TestModel {
objectId = 4;
},
[5] TestModel {
objectId = 5;
},
[6] TestModel {
objectId = 6;
},
[7] TestModel {
objectId = 7;
},
[8] TestModel {
objectId = 8;
},
[9] TestModel {
objectId = 9;
},
[10] TestModel {
objectId = 10;
},
[11] TestModel {
objectId = 11;
},
[12] TestModel {
objectId = 12;
},
[13] TestModel {
objectId = 13;
},
[14] TestModel {
objectId = 14;
},
[15] TestModel {
objectId = 15;
},
[16] TestModel {
objectId = 16;
},
[17] TestModel {
objectId = 17;
},
[18] TestModel {
objectId = 18;
},
[19] TestModel {
objectId = 19;
},
[20] TestModel {
objectId = 20;
},
[21] TestModel {
objectId = 21;
},
[22] TestModel {
objectId = 22;
},
[23] TestModel {
objectId = 23;
},
[24] TestModel {
objectId = 24;
},
[25] TestModel {
objectId = 25;
},
[26] TestModel {
objectId = 26;
},
[27] TestModel {
objectId = 27;
},
[28] TestModel {
objectId = 28;
}
)
"

Replace *CollectionView in my comment with *TableView :). The assertions / data source considerations are the same for each. One good practice is to remove usage of reloadData as well - using edit operations is more efficient and makes it easier to maintain consistency.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

JS1010111 picture JS1010111  Â·  5Comments

MarvinNazari picture MarvinNazari  Â·  8Comments

haashem picture haashem  Â·  5Comments

GitGadd picture GitGadd  Â·  4Comments

Luis-X picture Luis-X  Â·  7Comments