roubachof/Sharpnado.CollectionView

CollectionView crashes with iOS 16.5

Closed this issue · 2 comments

Platform (please complete the following information):

  • OS: [iOS]
  • Device: [iPhone6/iPhoneSimulator]
  • Sdk vervion: [iOS 16.5]
  • Xamarin.Forms: [5.0.0.2545]

Describe the bug
With iOS 16.4 something changed with UICollectionViewController.
If you have the data in a ObservableCollection and then try to update the data source. For example:

data.Clear();
for(...){
data.Add();
}

the app is crashing. This describes the bug in detail: https://developer.apple.com/forums/thread/728797

Exceptions (if applicable)
2023-06-20 13:07:26.126 Xamarin.PreBuilt.iOS[753:142424] Xamarin.iOS: Aborting due to unhandled Objective-C exception:
Invalid batch updates detected: the number of sections and/or items returned by the data source before and/or after performing the batch updates are inconsistent with the updates.
Data source before updates = { 1 section with item counts: [1] }
Data source after updates = { 1 section with item counts: [1] }
Updates = [
Insert item (0 - 0)
]
Collection view: <UICollectionView: 0x1124a5200; frame = (0 0; 371 150); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x280bdf690>; backgroundColor = UIExtendedSRGBColorSpace -1 -1 -1 0; layer = <CALayer: 0x280c6c3a0>; contentOffset: {0, 0}; contentSize: {170, 150}; adjustedContentInset: {0, 0, 0, 0}; layout: <Sharpnado_CollectionView_iOS_Renderers_SnappingCollectionViewLayout: 0x111fbfd80>; dataSource: <Sharpnado_CollectionView_iOS_Renderers_iOSViewSource: 0x28459b9a0>>

0x100cd6ce0 - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : mono_handle_native_crash

Native stacktrace:

=================================================================
Native Crash Reporting

Got a abrt while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries

0x100ce02e8 - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : mono_dump_native_crash_info

0x100e4e654 - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : xamarin_UIApplicationMain

0x100e66518 - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : xamarin_register_assembly

0x100cdf830 - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : sigabrt_signal_handler
0x2037a52f4 - /usr/lib/system/libsystem_platform.dylib : <redacted>
0x2038475f8 - /usr/lib/system/libsystem_pthread.dylib : pthread_kill
0x1c07b04b8 - /usr/lib/system/libsystem_c.dylib : abort

0x100e89d88 - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : do_icall

0x100e6c330 - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : xamarin_process_nsexception_using_mode

0x100d93998 - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : mono_runtime_invoke_checked
0x100d9a014 - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : mono_runtime_try_invoke_array
0x100d43504 - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : ves_icall_InternalInvoke
0x100d53794 - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : ves_icall_InternalInvoke_raw
0x100e89dc8 - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : do_icall
0x100e884fc - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : do_icall_wrapper

The app has been terminated.
0x100e7d980 - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : interp_runtime_invoke
0x100ce6f70 - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : mono_jit_runtime_invoke
0x100d93998 - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : mono_runtime_invoke_checked
0x100d98c0c - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : mono_runtime_exec_main_checked
0x100ccb850 - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : mono_jit_exec
0x100e7b7f0 - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : xamarin_main
0x100c92700 - /private/var/
0x100e7f3f0 - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : interp_exec_method_full

containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : main
0x1d713b344 - /usr/lib/dyld :

=================================================================
Basic Fault Address Reporting

Memory around native instruction pointer (0x1f43c1158):0x1f43c1148 c0 03 5f d6 c0 03 5f d6 10 29 80 d2 01 10 00 d4 .......)......
0x1f43c1158 e3 00 00 54 fd 7b bf a9 fd 03 00 91 73 ee ff 97 ...T.{......s...
0x1f43c1168 bf 03 00 91 fd 7b c1 a8 c0 03 5f d6 c0 03 5f d6 .....{........
0x1f43c1178 fd 7b bf a9 fd 03 00 91 50 00 80 d2 01 10 00 d4 .{......P.......

=================================================================
Managed Stacktrace:

  • Assertion: should not be reached at /Users/builder/jenkins/workspace/archive-mono/2020-02/ios/release/mono/mini/mini-exceptions.c:452

    0x100ce6f70 - /private/var/containers/Bundle/Application/F17CE279-1B4C-43F1-957C-AE434773BB90/XX.YY.iOS.app/Xamarin.PreBuilt.iOS : mono_jit_runtime_invoke

I'm seeing this too. It doesn't happen consistently, but sometimes after a collection 'reset' event that is immediately followed by collection adds. When it does fail, it is always as the second collection item is being added (the first item having been added during the reset event). Putting a Thread.Sleep() in the background service populating the underlying observables made the error disappear (though that's not an actual solution...)

Tracing the code, I found that the GetItemsCount override in iOSViewSource was usually getting called after every reset event (as well as subsequent adds). However, in every case where this error came up, GetItemsCount was not called. My hunch is that the framework code making this check isn't running sometimes and getting out of sync.

I found this stack overflow post from 2017 describing something that sounds very similar. I tried adding this line in CollectionViewRenderer right after the assignment to Control.DataSource at line 374:

Control.NumberOfItemsInSection(0);

...and that seems to have fixed it 🤷‍♂️

My workaround is not calling data.Clear();
Instead remove each item from the ObservableCollection:

for(int i = data.Count - 1; i >= 0; i--) {
	data.RemoveAt(i);
}