Bug 410 - Internal exception when handling Clicked events for buttons within a toolbar
Summary: Internal exception when handling Clicked events for buttons within a toolbar
Status: RESOLVED FIXED
Alias: None
Product: iOS
Classification: Xamarin
Component: XI runtime ()
Version: 4.x
Hardware: All Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2011-08-25 08:00 UTC by Patrick Westerhoff
Modified: 2011-08-31 20:28 UTC (History)
2 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description Patrick Westerhoff 2011-08-25 08:00:02 UTC
Hey,

I was trying to add multiple buttons on one side of a NavigationController‘s navigation bar. According to multiple examples on the internet[1][2], this is usually done by placing the `UIBarButtonItem`s inside a `UIToolbar` and using the custom view functionality of the `UIBarButtonItem` to display that toolbar as the “single button”.

Porting the Objective-C example code on those website to MonoTouch worked fine, and in fact the buttons are displayed just fine. However when adding an event listener to the `Clicked` event (don‘t know if this happens with other events too), I get an Object-C exception when the button is clicked.

As already shown in my StackOverflow question[3], this is the error I am receiving:

    Error connecting stdout and stderr (127.0.0.1:10001)
    Stacktrace:
    
      at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication.UIApplicationMain (int,string[],intptr,intptr) <IL 0x0009f, 0xffffffff>
      at MonoTouch.UIKit.UIApplication.Main (string[],string,string) [0x00038] in /Developer/MonoTouch/Source/monotouch/monotouch/UIKit/UIApplication.cs:26
      at TestProject.Application.Main (string[]) [0x00000] in /Users/Apple/Projects/TestProject/TestProject/Main.cs:16
      at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object (object,intptr,intptr,intptr) <IL 0x00050, 0xffffffff>
    
    Native stacktrace:
    
    	0   TestProject                         0x000d0de8 mono_handle_native_sigsegv + 343
    	1   TestProject                         0x0000f74c mono_sigsegv_signal_handler + 322
    	2   libSystem.B.dylib                   0x906fc45b _sigtramp + 43
    	3   ???                                 0xffffffff 0x0 + 4294967295
    	4   libobjc.A.dylib                     0x02a02753 prepareForMethodLookup + 93
    	5   libobjc.A.dylib                     0x029f9069 lookUpMethod + 86
    	6   libobjc.A.dylib                     0x029f91d6 _class_lookupMethodAndLoadCache + 40
    	7   libobjc.A.dylib                     0x02a0c0e3 objc_msgSend + 87
    	8   UIKit                               0x01ee6cc3 -[UIBarButtonItem(UIInternal) _sendAction:withEvent:] + 156
    	9   UIKit                               0x01cd44fd -[UIApplication sendAction:to:from:forEvent:] + 119
    	10  UIKit                               0x01d64799 -[UIControl sendAction:to:forEvent:] + 67
    	11  UIKit                               0x01d66c2b -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
    	12  UIKit                               0x01d657d8 -[UIControl touchesEnded:withEvent:] + 458
    	13  UIKit                               0x01cf8ded -[UIWindow _sendTouchesForEvent:] + 567
    	14  UIKit                               0x01cd9c37 -[UIApplication sendEvent:] + 447
    	15  UIKit                               0x01cdef2e _UIApplicationHandleEvent + 7576
    	16  GraphicsServices                    0x0404f992 PurpleEventCallback + 1550
    	17  CoreFoundation                      0x00ea2944 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
    	18  CoreFoundation                      0x00e02cf7 __CFRunLoopDoSource1 + 215
    	19  CoreFoundation                      0x00dfff83 __CFRunLoopRun + 979
    	20  CoreFoundation                      0x00dff840 CFRunLoopRunSpecific + 208
    	21  CoreFoundation                      0x00dff761 CFRunLoopRunInMode + 97
    	22  GraphicsServices                    0x0404e1c4 GSEventRunModal + 217
    	23  GraphicsServices                    0x0404e289 GSEventRun + 115
    	24  UIKit                               0x01ce2c93 UIApplicationMain + 1160
    	25  ???                                 0x077efe64 0x0 + 125763172
    	26  ???                                 0x077ef1e2 0x0 + 125759970
    	27  ???                                 0x077ef0be 0x0 + 125759678
    	28  ???                                 0x077ef145 0x0 + 125759813
    	29  TestProject                         0x0000f507 mono_jit_runtime_invoke + 1332
    	30  TestProject                         0x001ed259 mono_runtime_invoke + 137
    	31  TestProject                         0x001ef940 mono_runtime_exec_main + 669
    	32  TestProject                         0x001eed2a mono_runtime_run_main + 843
    	33  TestProject                         0x000a3093 mono_jit_exec + 200
    	34  TestProject                         0x002a163d main + 4060
    	35  TestProject                         0x00002819 _start + 208
    	36  TestProject                         0x00002748 start + 40
    
    Debug info from gdb:
    
    dyld: could not load inserted library: /Users/Apple/Library/Application Support/iPhone Simulator/4.3/Applications/86C48AC1-821F-49DD-B344-58471F02D31B/TestProject.app/monotouch-fixes.dylib
    
    =================================================================
    Got a SIGSEGV while executing native code. This usually indicates
    a fatal error in the mono runtime or one of the native libraries 
    used by your application.
    =================================================================


And this is the (full) code I am using to test this:

>> Main.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using MonoTouch.Foundation;
    using MonoTouch.UIKit;
    
    namespace TestProject
    {
        [Register("AppDelegate")]
        public class Application : UIApplicationDelegate
        {
            private UIWindow window;
            
            public static void Main ( string[] args )
            {
                UIApplication.Main( args, "UIApplication", "AppDelegate" );
            }
            
            public override bool FinishedLaunching ( UIApplication app, NSDictionary options )
            {
                window = new UIWindow( UIScreen.MainScreen.Bounds );
                window.AddSubview( ( new UINavigationController( new Test() ) ).View );
                window.MakeKeyAndVisible();
                return true;
            }
        }
    }

>> Test.cs
    using System;
    using System.Drawing;
    using MonoTouch.UIKit;
    
    namespace TestProject
    {
        public class Test : UIViewController
        {
            public override void ViewDidLoad ()
            {
                base.ViewDidLoad();
                
                UIBarButtonItem btn1 = new UIBarButtonItem( "foo", UIBarButtonItemStyle.Bordered, delegate(object sender, EventArgs e) {
                    Console.WriteLine( "asdf" );
                } );
                
                UIBarButtonItem btn2 = new UIBarButtonItem();
                btn2.Style = UIBarButtonItemStyle.Bordered;
                btn2.Title = "bar";
                btn2.Clicked += delegate(object sender, EventArgs e) {
                    Console.WriteLine( "fdsa" );
                };
                
                UIToolbar tb = new UIToolbar( new RectangleF( 0, 0, 150, 44.0f ) );
                tb.SetItems( new UIBarButtonItem[] { btn1, btn2 }, false );
                NavigationItem.RightBarButtonItem = new UIBarButtonItem( tb );
            }
        }
    }



Thank you very much for your help!

Patrick Westerhoff


[1]: www.mattdipasquale.com/blog/2010/11/02/how-to-add-multiple-uibarbuttonitems-to-uinavigationbar/
[2]: www.mattdipasquale.com/blog/2010/11/02/how-to-add-multiple-uibarbuttonitems-to-uinavigationbar/
[3]: http://stackoverflow.com/questions/7189415/handling-multiple-buttons-in-uitoolbar
Comment 1 Patrick Westerhoff 2011-08-25 09:05:49 UTC
Apparently this can be easily fixed by declaring the `UIBarButtonItem`s as instance members. That way they won‘t be removed by the GC.

However I think the GC should still be able to recognize that there are still those objects within the `Toolbar` instance.

See also the answer to my StackOverflow question: http://stackoverflow.com/questions/7189415/handling-multiple-buttons-in-uitoolbar/7189641#7189641
Comment 2 Sebastien Pouliot 2011-08-25 10:27:12 UTC
It's a bug inside MonoTouch. 

The array you're providing is not kept, nor copied, by SetItems. As such there's no (managed) reference to the 'btn1' and 'btn2' after the call to SetItems and the GC is collecting them.

The workaround (like the answer in stackoverflow) is to keep your own reference to those objects.
Comment 3 Sebastien Pouliot 2011-08-31 20:28:43 UTC
Fixed. Using SetItems now match with using Items getter/setter and that resolve the GC issue you were hitting.

Workrounds (until fix is available):
a) use Items setter, not SetItem (but lose animation);
b) keep a reference (e.g. field) to the array of buttons before calling SetItems

Thanks for providing the test case!