Forum Xamarin.Forms

Assertion failure in UITableView when updating viewmodel databound to ListView

I'm developing a Xamarin Forms app that asynchronously gets updated models from the server that need to be merged into the information shown in the UI. I accomplish this by having my viewmodels subscribe to a MessagingCenter topic to which the updated models are broadcasted. When the viewmodels receive the message, they merge in the updated data, and it appears in the UI via data-binding.

This works fine on Android, but on iOS, when an update is made to the viewmodel I get this error, which crashes the app:

*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit/UIKit-3318.16.14/UITableView.m:1582

It seems to me like this should work, so I filed a bug on it along with a project that reproduces the problem: Xamarin bug.

Has anyone else seen this? Is there a different approach I should be taking to update the data shown in the view?

Posts

  • adamkempadamkemp USInsider, Developer Group Leader mod

    That probably is a bug, but I would suggest not trying to update the list one item at a time. Because that property is an ObservableCollection every change is reflected into the UI (possibly with an animation), which is going to be at best expensive. What you should do instead is replace the whole list atomically:

        public TheModel ()
        {
            MessagingCenter.Subscribe<TheService, TheModelItem[]> (TheService.Instance, "ModelChanged", (s, newItems) => {
                if (!Loading) {
                    Items = new ObservableCollection<TheModelItem>(newItems);
                }
            });
        }
    
        public async Task Load ()
        {
            Loading = true;
            var items = await TheService.Instance.Load ();
            Items = new ObservableCollection<TheModelItem> (items);
            Loading = false;
        }
    
  • Thanks @adamkemp. Doing it the way you suggest does avoid this crashing problem. Unfortunately, although this fix works in the sample I created, my real app is still crashing somewhere on merging in the updated data even with the fix. I must have some other problem besides this ListView update issue. This other bug isn't caught by Xamarin, so the only info I have so far is the iOS crash log:

    Exception Type:  EXC_CRASH (SIGABRT)
    Exception Codes: 0x0000000000000000, 0x0000000000000000
    Triggered by Thread:  8
    
    Last Exception Backtrace:
    0   CoreFoundation                  0x29eedc1a __exceptionPreprocess + 122
    1   libobjc.A.dylib                 0x37698c86 objc_exception_throw + 34
    2   CoreFoundation                  0x29eed924 -[NSException raise] + 4
    3   portableiOS                     0x007a24dc 0x3a000 + 7767260
    4   portableiOS                     0x0289cc90 0x3a000 + 42347664
    5   portableiOS                     0x0289c804 0x3a000 + 42346500
    6   portableiOS                     0x00087324 0x3a000 + 316196
    7   portableiOS                     0x00add188 0x3a000 + 11153800
    8   portableiOS                     0x00ad7558 0x3a000 + 11130200
    9   portableiOS                     0x00c55f88 0x3a000 + 12697480
    10  portableiOS                     0x02dbb9c6 0x3a000 + 47716806
    11  portableiOS                     0x02e2483c 0x3a000 + 48146492
    12  portableiOS                     0x02da31d8 0x3a000 + 47616472
    13  portableiOS                     0x02dbc626 0x3a000 + 47719974
    14  portableiOS                     0x02df98f0 0x3a000 + 47970544
    15  portableiOS                     0x02e129de 0x3a000 + 48073182
    16  portableiOS                     0x02e2a6de 0x3a000 + 48170718
    17  libsystem_pthread.dylib         0x37d5be8e _pthread_body + 134
    18  libsystem_pthread.dylib         0x37d5be02 _pthread_start + 114
    19  libsystem_pthread.dylib         0x37d59b8c thread_start + 4
    

    Oh well, back to peeling the onion.

  • adamkempadamkemp USInsider, Developer Group Leader mod

    That stack is useless without symbols and the console output.

  • Yes, sorry about that. After poking around I found that in a custom renderer I was making UI calls without using InvokeOnMaintThread. Since fixing that I haven't seen this bug, so for lack of better proof I'm assuming that fixed the problem.

Sign In or Register to comment.