Xamarin.forms: [Bug] [iOS] Crash When the First Toolbar Item Has an Icon and a Second Item Gets Added

Created on 3 Jun 2019  ·  19Comments  ·  Source: xamarin/Xamarin.Forms

Steps to Reproduce

  1. Build the reproduction project.
  2. Tap on a toolbar item.

The relevant code:

public MainPage()
{
    item0 = new ToolbarItem("Item 0", null, ClearAndAddToolbarItems)
    {
        IconImageSource = ImageSource.FromResource("CrashTest.Image_0.png")
    };
    item1 = new ToolbarItem("Item 1", null, ClearAndAddToolbarItems)
    {
        // It doesn't matter if this item has an image or not.
        //IconImageSource = ImageSource.FromResource("CrashTest.Image_1.png")
    };
    ClearAndAddToolbarItems();
    InitializeComponent();
}

private void ClearAndAddToolbarItems()
{
    ToolbarItems.Clear();
    ToolbarItems.Add(item0);
    ToolbarItems.Add(item1);
}

Expected Behavior

No crashs.

Actual Behavior

Unhandled Exception:
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'PrimaryToolbarItem'.
  at Foundation.NSObject.get_SuperHandle () [0x00012] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.8.0.2/src/Xamarin.iOS/Foundation/NSObject2.cs:449 
  at UIKit.UIBarButtonItem.set_Image (UIKit.UIImage value) [0x00033] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.8.0.2/src/Xamarin.iOS/UIKit/UIBarButtonItem.g.cs:653 
  at Xamarin.Forms.Platform.iOS.ToolbarItemExtensions+PrimaryToolbarItem.UpdateIconAndStyle () [0x0007e] in <db147fad2aa9412c845ff0ead92dfe20>:0 
  at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.8.0.2/src/Xamarin.iOS/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1023 
  at Foundation.NSAsyncSynchronizationContextDispatcher.Apply () [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.8.0.2/src/Xamarin.iOS/Foundation/NSAction.cs:178 
--- End of stack trace from previous location where exception was thrown ---

  at (wrapper managed-to-native) UIKit.UIApplication.UIApplicationMain(int,string[],intptr,intptr)
  at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.8.0.2/src/Xamarin.iOS/UIKit/UIApplication.cs:79 
  at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0002c] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.8.0.2/src/Xamarin.iOS/UIKit/UIApplication.cs:63 
  at CrashTest.iOS.Application.Main (System.String[] args) [0x00001] in /Users/user/Projects/CrashTest/CrashTest.iOS/Main.cs:17

Basic Information

  • Version with issue: 4.0.0.425677
  • Last known good version: None
  • IDE: Vidual Studio 2019 for Mac
  • Platform Target Frameworks:

    • iOS: 12.2

  • Nuget Packages: Xamarin.Forms
  • Affected Devices: iOS

Reproduction Link

https://drive.google.com/file/d/14VnLQbRIGfDIYxrX6IKK5Bd3cIglrk3I/view?usp=sharing

3 high high impact iOS 🍎 bug

Most helpful comment

Actually, by further investigation we think this crash is related to

CachedImageRenderer.InitImageSourceHandler();

from FFImageLoading library and issue should potentially be opened there.
We commented it out and are now waiting to see if the transient crashes will go away. So far it looks good.

All 19 comments

It does seem to have something to do with the fact that at least one of the items has an icon.

This line in the error:

barItem.UpdateIconAndStyle () [0x0007e] in :0

Made me try to comment out the IconImageSource line for item0. When you do that, the code works as expected. After some more digging, I found out it is also fine if you use a ImageSource.FromFile("About.png") instead of the FromResource.

It does seem to have something to do with the fact that at least one of the items has an icon.

The first item must have an icon to trigger the exception. If the first item has not an icon, but the second one has, it works as expected without an exception.

+1 to fix this. Anyone found a workaround? @jfversluis We use ImageSource.FromFile() for both toolbar items but it seems that it doesn't help. So it is related to how it is named in the title I guess.
Additionally, I can confirm that the issue is of transient nature, it doesn't happen always. If the changes in the toolbar items/icons happen during navigation between pages, it happens usually then. We use AppShell, maybe that additionally increases the chances of reproducing it.

Additionally, we keep the references of toolbarItems in code behind, and we change the icons dynamically to represent the state of background sync and device connection. We add the try-catch code, but the exception can not be caught, it just crashes the app. So I would kindly ask for a bit more defensive programming, try-catch here and there in the framework, prevention of NPEs with ?. and as operator, here and there. Because we already stumbled upon several issues in xamarin framework where the uncaught exceptions in the framework completely crash our app and we can not do anything to prevent it, other than some time consuming hacks, if we are able to find them.

Actually, by further investigation we think this crash is related to

CachedImageRenderer.InitImageSourceHandler();

from FFImageLoading library and issue should potentially be opened there.
We commented it out and are now waiting to see if the transient crashes will go away. So far it looks good.

Great find @brcinho keep us updated on further developments

I had this crash as well using the shared resources in the Xamarin.Forms project:

var image = ImageSource.FromResource("NameSpaceTo.Resources.EN.png", typeof(CustomPageContainer).GetTypeInfo().Assembly);
LanguageButton.IconImageSource = image;

I am running into this now. I started using Xamarin around half a year ago and am starting to regret my decision as it feels like I'm running into every single bug, and that they don't get fixed. How can a crash bug like this be open for over a year? I have contributed a lot of open source packages to the Xamarin community and it is affecting this one that I just released: https://github.com/Tommigun1980/IOSToolbarExtensions

I would really like some support from the developers now as this has to get fixed. If you open the url I linked to you can see a screenshot of the menus with which I get this crash to happen around 10% of the times the menu gets rendered:
Primary items: Cancel (text), Save (text), Three dots (icon, dynamically added)
Secondary items: Language (text + icon), My Logins (text), Log Out (text), Delete Account (text).
The three dots primary icon is dynamically added, and the secondary items get deleted from the content page by the renderer (as it takes care of rendering them). The deletion of the items happens from ViewWillAppear on the UI thread.
I suspect it is the Xamarin.Forms's navigation bar renderer's secondary item render that is crashing, and has to do with my renderer removing the secondary items (to prevent Xamarin from drawing the faux secondary menu). The deletion happens on the UI thread so shouldn't this be safe? You can also find the sources for the renderer in the repo.

Stack trace:

"Cannot access a disposed object.\nObject name: 'SecondaryToolbarItem'."

at Foundation.NSObject.get_SuperHandle () [0x00012] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.18.2.1/src/Xamarin.iOS/Foundation/NSObject2.cs:449
at UIKit.UIBarButtonItem.get_CustomView () [0x0002a] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.18.2.1/src/Xamarin.iOS/UIBarButtonItem.g.cs:594
at Xamarin.Forms.Platform.iOS.ToolbarItemExtensions+SecondaryToolbarItem.UpdateIcon () [0x0009f] in D:\\a\\1\\s\\Xamarin.Forms.Platform.iOS\\Extensions\\ToolbarItemExtensions.cs:150
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021
at Foundation.NSAsyncSynchronizationContextDispatcher.Apply () [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.18.2.1/src/Xamarin.iOS/Foundation/NSAction.cs:178
--- End of stack trace from previous location where exception was thrown ---

  at (wrapper managed-to-native) UIKit.UIApplication.UIApplicationMain(int,string[],intptr,intptr)
    at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.18.2.1/src/Xamarin.iOS/UIKit/UIApplication.cs:86
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0000e] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.18.2.1/src/Xamarin.iOS/UIKit/UIApplication.cs:65
at MyApp.iOS.Application.Main (System.String[] args) [0x00001] in /Users/myname/Projects/MyAppous/MyApp.iOS/Main.cs:13

Please work with me on getting this fixed or please fix the issue. I am nearing the completion of my application and these crashes have to be solved. You are promoting Xamarin so when people actually adopt it you can not leave them hanging by not supporting them and fixing critical crash bugs. Please let me know if there is anything I can do to help you in fixing this.

Thank you.

Can confirm this is related to using FFImageLoading. See the bug in their repo: https://github.com/luberda-molinet/FFImageLoading/issues/1460
Though I am not sure where this bug originates.

I am not using FFImageLoafing for the icons, but I do have it in the
project as a dependency. Are you saying it’s intercepting the calls?

A comment in the bug report states “In addition, there are no problems when using IconImageSource for ContentPage or something else.”, isn’t that contradictory?

On Monday, July 27, 2020, Fabian Schipp notifications@github.com wrote:

Can confirm this is related to using FFImageLoading. See the bug in their
repo: luberda-molinet/FFImageLoading#1460
https://github.com/luberda-molinet/FFImageLoading/issues/1460
Though I am not sure where this bug originates.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/xamarin/Xamarin.Forms/issues/6387#issuecomment-664384542,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AOL6P6FMNZR3MM3K6HTMF2TR5V3XRANCNFSM4HSHWU4Q
.

--

I know, but on my side it crashes 100% when I do the following:

  • use CachedImageRenderer.InitImageSourceHandler(); to initialise the FFImageLoading
  • use an IconImageSource for a ToolbarItem on a ContentPage

But then it's not related to using FFImageLoading, rather than FFImageLoading also crashing
due to this.

On Tue, Jul 28, 2020 at 7:52 AM Fabian Schipp notifications@github.com
wrote:

I know, but on my side it crashes 100% when I do the following:

  • use CachedImageRenderer.InitImageSourceHandler(); to initialise the
    FFImageLoading
  • use an IconImageSource for a ToolbarItem on a ContentPage


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/xamarin/Xamarin.Forms/issues/6387#issuecomment-664775487,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AOL6P6CSS4MGDG2PT5YSU73R5ZKQZANCNFSM4HSHWU4Q
.

I have noticed that the crash happens 100% on the first time the menu is rendered on a clean install. Consecutive boots of the app don't show this issue. After it has crashed once, I can not reproduce the crash until I reinstall the app, after which it always happens once the first time it renders the menu.

Please help.

Hi guys. I am somewhat nearing release, and this crash bug is effectively preventing it. Please advice on a workaround, or could this be prioritised? It's a crash bug after all.

Thanks!

I also ran into this issue yesterday and, to my surprise, found that nobody seems to have reported this issue to the FFImageLoading-team yet, notwithstanding the fact that this clearly seems to be an issue to do with that library. That is, the line causing issues is CachedImageRenderer.InitImageSourceHandler(); in your AppDelegate - removing it will prevent the crash.

Since this line appears to only enable FFImageLoading on image types no directly related to FFImageLoading itself, an easy work-around would be to consistently use FFImageLoading's own controls throughout your app, and disable the aforementioned line in your AppDelegate (this should be possible, assuming you're not loading external images into native controls, such as ToolbarItems, ImageButtons, etc.).

Another work-around that allows you to leave the FFImageLoading's initialization in place is to simply put a delay on insertion of your toolbar item. If inserted a while after the page has been rendered, the app doesn't crash either. As such, it may be enough to simply insert your toolbar item on the page's OnAppearing.

To get things moving with FFImageLoading, I filed a bug report there.

Also happens with Xamarin.Forms.Nuke.

I guess it happens if you use a custom Image Source Handler and has nothing to do with FFImageLoading specifically.

This seems to be definitely a crash in Xamarin.Forms
Image = await _item.IconImageSource.GetNativeImageAsync();

Apparently the default implementation by Xamarin.Forms (https://github.com/xamarin/Xamarin.Forms/blob/f35ae07a0a8471d255f7a1ebdd51499e10e0a4cb/Xamarin.Forms.Platform.iOS/Renderers/ImageRenderer.cs) is not really async, it returns without awaiting - therefor there is no time for the control to get disposed. If the implementation, either by FFImageLoading or Xamarin.Forms.Nuke or any other implementation is really async, the toolbar control can be disposed in the meantime and then the crash happens.

@samhouts This seems to be definitely a crash bug in Xamarin.Forms and is not related to either library. I can also imagine other code parts, where there is the same bug.

Before assigning Image of PrimaryToolbarItem or SecondaryToolbarItem, there has to be a check, if the control has been disposed. (Again, this has to be everywhere, where there is Code similar to await _item.IconImageSource.GetNativeImageAsync())

@acuntex My original issue is definitely related to Xamarin.Forms. It's so minimalistic that it can't be anything else.

@abduelhamit Absolutely.
You can see here:
https://github.com/xamarin/Xamarin.Forms/blob/79cc0f49fe90a59f02aa0490072b449ccdad4a27/Xamarin.Forms.Core/StreamImageSource.cs
that Streams are loaded async (unlike simple FileImageSources that are loaded directly).

Same would happen if you would use a remote image as toolbar item.

@samhouts Any update? This is a crash bug.

Was this page helpful?
0 / 5 - 0 ratings