2
votes

The Code:

UIButton rightButton = UIButton.FromType (UIButtonType.DetailDisclosure);

rightButton.TouchUpInside += (o, e) => { Console.WriteLine("hello"); };

Stacktrace:

...

Native stacktrace:

0   taggr                               0x000908fc mono_handle_native_sigsegv + 284
1   taggr                               0x00005c98 mono_sigsegv_signal_handler + 248
2   libsystem_c.dylib                   0x95c2859b _sigtramp + 43
3   ???                                 0xffffffff 0x0 + 4294967295
4   UIKit                               0x0219355a -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61
5   UIKit                               0x02238b76 -[UIControl sendAction:to:forEvent:] + 66
6   UIKit                               0x0223903f -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 503
7   UIKit                               0x022382fe -[UIControl touchesEnded:withEvent:] + 549
8   UIKit                               0x021b8a30 -[UIWindow _sendTouchesForEvent:] + 513
9   UIKit                               0x021b8c56 -[UIWindow sendEvent:] + 273
10  UIKit                               0x0219f384 -[UIApplication sendEvent:] + 464
11  UIKit                               0x02192aa9 _UIApplicationHandleEvent + 8196
12  GraphicsServices                    0x0478afa9 PurpleEventCallback + 1274
13  CoreFoundation                      0x011951c5 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
14  CoreFoundation                      0x010fa022 __CFRunLoopDoSource1 + 146
15  CoreFoundation                      0x010f890a __CFRunLoopRun + 2218
16  CoreFoundation                      0x010f7db4 CFRunLoopRunSpecific + 212
17  CoreFoundation                      0x010f7ccb CFRunLoopRunInMode + 123
18  GraphicsServices                    0x04789879 GSEventRunModal + 207
19  GraphicsServices                    0x0478993e GSEventRun + 114
20  UIKit                               0x02190a9b UIApplicationMain + 1175
21  ???                                 0x09ff8784 0x0 + 167741316
22  ???                                 0x09ff79d0 0x0 + 167737808
23  ???                                 0x09ff7878 0x0 + 167737464
24  ???                                 0x09ff7907 0x0 + 167737607
25  taggr                               0x0000a002 mono_jit_runtime_invoke + 722
26  taggr                               0x00169efe mono_runtime_invoke + 126
27  taggr                               0x0016dfe4 mono_runtime_exec_main + 420
28  taggr                               0x00173405 mono_runtime_run_main + 725
29  taggr                               0x00067205 mono_jit_exec + 149
30  taggr                               0x002116d5 main + 2837
31  taggr                               0x00003055 start + 53

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.

1

1 Answers

4
votes

That code is both right and wrong depending on it's context. Let's assume it's wrong (with the stack trace) because it's used like:

void BadCase ()
{
    UIButton rightButton = UIButton.FromType (UIButtonType.DetailDisclosure);
    rightButton.TouchUpInside += (o, e) => { Console.WriteLine("hello"); };
}

In this case rightButton can be collected (by the garbage collector) once the method returns (since there's no managed reference to the local variable). However the native button can still exists and will try to call back (into managed code) when a touch event occurs. This will lead to a crash (since the managed instance was collected).

UIButton rightButton;

void GoodCase ()
{
    rightButton = UIButton.FromType (UIButtonType.DetailDisclosure);
    rightButton.TouchUpInside += (o, e) => { Console.WriteLine("hello"); };
}

You can easily avoid this by keeping a reference to the button, e.g. by promoting it from a local variable to a field. That will prevent the GC to collect the managed button until the instance (of the type) is disposed. This means the native button will be able to call back into managed land and output your hello.