Hey all,
I am currently struggling to find a solution to a problem I am facing. I have a couple of behaviors attached to certain pages in my app and when I navigate back and forth it doesn't matter to which page it crashes the app. I get the following error output:
2017-01-27 11:14:46.878 BNApp.iOS[2888:22873]
Unhandled Exception:
System.NullReferenceException: Object reference not set to an instance of an object
at BNApp.Behaviors.EventToCommandBehavior.DeregisterEvent (System.String name) [0x0001e] in C:\TFS\BN\BNApp\BNApp\BNApp\BNApp\Behaviors\EventToCommandBehavior.cs:83
at BNApp.Behaviors.EventToCommandBehavior.OnDetachingFrom (Xamarin.Forms.VisualElement bindable) [0x00009] in C:\TFS\BN\BNApp\BNApp\BNApp\BNApp\Behaviors\EventToCommandBehavior.cs:51
at Xamarin.Forms.Behavior`1[T].OnDetachingFrom (Xamarin.Forms.BindableObject bindable) [0x00000] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\Interactivity\Behavior.cs:57
at Xamarin.Forms.Behavior.Xamarin.Forms.IAttachedObject.DetachFrom (Xamarin.Forms.BindableObject bindable) [0x00000] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\Interactivity\Behavior.cs:27
at Xamarin.Forms.AttachedCollection`1[T].OnDetachingFrom (Xamarin.Forms.BindableObject bindable) [0x0000f] in C:\BuildAg
ent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\Interactivity\AttachedCollection.cs:75
at Xamarin.Forms.AttachedCollection`1[T].DetachFrom (Xamarin.Forms.BindableObject bindable) [0x00000] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\Interactivity\AttachedCollection.cs:32
at Xamarin.Forms.VisualElement.Finalize () [0x0001d] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\VisualElement.cs:789
2017-01-27 11:14:46.879 BNApp.iOS[2888:22873] Unhandled managed exception:
Object reference not set to an instance of an object (System.NullReferenceException)
at BNApp.Behaviors.EventToCommandBehavior.DeregisterEvent (System.String name) [0x0001e] in C:\TFS\BN\BNApp\BNApp\BNApp\BNApp\Behaviors\EventToCommandBehavior.cs:83
at BNApp.Behaviors.EventToCommandBehavior.OnDetachingFrom (Xamarin.Forms.VisualElement bindable) [0x00009] in C:\TFS\BN\BNApp\BNApp\BNApp\BNApp\Behaviors\EventToCommandBehavior.cs:51
at Xamarin.Forms.Behavior`1[T].OnDetachingFrom (Xamarin.Forms.BindableObject bindab
le) [0x00000] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\Interactivity\Behavior.cs:57
at Xamarin.Forms.Behavior.Xamarin.Forms.IAttachedObject.DetachFrom (Xamarin.Forms.BindableObject bindable) [0x00000] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\Interactivity\Behavior.cs:27
at Xamarin.Forms.AttachedCollection`1[T].OnDetachingFrom (Xamarin.Forms.BindableObject bindable) [0x0000f] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\Interactivity\AttachedCollection.cs:75
at Xamarin.Forms.AttachedCollection`1[T].DetachFrom (Xamarin.Forms.BindableObject bindable) [0x00000] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\Interactivity\AttachedCollection.cs:32
at Xamarin.Forms.VisualElement.Finalize () [0x0001d] in C:\BuildAgent3\work\ca3766cfc22354a1\Xamarin.Forms.Core\VisualElement.cs:789
2017-01-27 11:14:46.880 BNApp.iOS[2888:22873] critical: Stacktrace:
2017-01-27 11:14:46.880 BNApp.iOS[2888:22873] critical:
Native stacktrace:
2017-01-27 11:14:46.972 BNApp.iOS[2888:22873] critical: 0 BNApp.iOS 0x00000001045a125d mono_handle_native_sigsegv + 253
2017-01-27 11:14:46.972 BNApp.iOS[2888:22873] critical: 1 libsystem_platform.dylib 0x00000001115a152a _sigtramp + 26
2017-01-27 11:14:46.972 BNApp.iOS[2888:22873] critical: 2 ??? 0x0000000104fb699b 0x0 + 4378552731
2017-01-27 11:14:46.973 BNApp.iOS[2888:22873] critical: 3 libsystem_c.dylib 0x00000001112fefd7 abort + 129
2017-01-27 11:14:46.973 BNApp.iOS[2888:22873] critical: 4 BNApp.iOS 0x000000010472de5f xamarin_unhandled_exception_handler + 47
2017-01-27 11:14:46.973 BNApp.iOS[2888:22873] critical: 5 BNApp.iOS 0x00000001045fd55b mono_invoke_unhandled_exception_hook + 139
2017-01-27 11:14:46.973 BNApp.iOS[2888:22873] critical: 6 BNApp.iOS 0x00000001046a3b9c mono_thread_internal_unhandled_exception + 156
2017-01-27 11:14:46.973 BNApp.iOS[2888:22873] critical: 7 BNApp.iOS 0x00000001045fffdb mono_gc_run_finalize + 1099
2017-01-27 11:14:46.973 BNApp.iOS[2888:22873] critical: 8 BNApp.iOS 0x00000001046c3dbc sgen_gc_invoke_finalizers + 220
2017-01-27 11:14:46.974 BNApp.iOS[2888:22873] critical: 9 BNApp.iOS 0x0000000104601b2a finalizer_thread + 618
2017-01-27 11:14:46.974 BNApp.iOS[2888:22873] critical: 10 BNApp.iOS 0x00000001046a4483 start_wrapper + 339
2017-01-27 11:14:46.974 BNApp.iOS[2888:22873] critical: 11 BNApp.iOS 0x000000010470dc72 inner_start_thread + 354
2017-01-27 11:14:46.974 BNApp.iOS[2888:22873] critical: 12 libsystem_pthread.dylib 0x00000001115b399d _pthread_body + 131
2017-01-27 11:14:46.974 BNApp.iOS[2888:22873] critical: 13 libsystem_pthread.dylib 0x00000001115b391a _pthread_body + 0
2017-01-27 11:14:46.974 BNApp.iOS[2888:22873] critical: 14 libsystem_pthread.dylib 0x00000001115b1351 thread_start + 13
2017-01-27 11:14:46.975 BNApp.iOS[2888:22873] critical:
=================================================================
Got a SIGABRT while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries
used by your application.
I am using the code sample for reusable EventToCommand behavior found here:
https://github.com/xamarin/xamarin-forms-samples/tree/master/Behaviors/EventToCommandBehavior
I have modified my solution a little bit by setting the T not to view but VisualElement.
public class EventToCommandBehavior : BehaviorBase<VisualElement>
{
private Delegate _eventHandler;
public static readonly BindableProperty EventNameProperty = BindableProperty.Create("EventName", typeof(string), typeof(EventToCommandBehavior), null, propertyChanged: OnEventNameChanged);
public static readonly BindableProperty CommandProperty = BindableProperty.Create("Command", typeof(ICommand), typeof(EventToCommandBehavior), null);
public static readonly BindableProperty CommandParameterProperty = BindableProperty.Create("CommandParameter", typeof(object), typeof(EventToCommandBehavior), null);
public static readonly BindableProperty InputConverterProperty = BindableProperty.Create("Converter", typeof(IValueConverter), typeof(EventToCommandBehavior), null);
public string EventName
{
get { return (string)GetValue(EventNameProperty); }
set { SetValue(EventNameProperty, value); }
}
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public object CommandParameter
{
get { return GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
public IValueConverter Converter
{
get { return (IValueConverter)GetValue(InputConverterProperty); }
set { SetValue(InputConverterProperty, value); }
}
protected override void OnAttachedTo(VisualElement bindable)
{
base.OnAttachedTo(bindable);
RegisterEvent(EventName);
}
protected override void OnDetachingFrom(VisualElement bindable)
{
base.OnDetachingFrom(bindable);
DeregisterEvent(EventName);
}
public void RegisterEvent(string name)
{
if (string.IsNullOrWhiteSpace(name))
{
return;
}
var eventInfo = AssociatedObject.GetType().GetRuntimeEvent(name);
if (eventInfo == null)
{
throw new ArgumentException($"EventToCommandBehavior: Can't register the '{EventName}' event.");
}
var methodInfo = typeof(EventToCommandBehavior).GetTypeInfo().GetDeclaredMethod("OnEvent");
_eventHandler = methodInfo.CreateDelegate(eventInfo.EventHandlerType, this);
eventInfo.AddEventHandler(AssociatedObject, _eventHandler);
}
public void DeregisterEvent(string name)
{
if (string.IsNullOrWhiteSpace(name))
{
return;
}
if (_eventHandler == null)
{
return;
}
var eventInfo = AssociatedObject.GetType().GetRuntimeEvent(name);
if (eventInfo == null)
{
throw new ArgumentException($"EventToCommandBehavior: Can't de-register the '{EventName}' event.");
}
eventInfo.RemoveEventHandler(AssociatedObject, _eventHandler);
_eventHandler = null;
}
public void OnEvent(object sender, object eventArgs)
{
if (Command == null)
{
return;
}
object resolvedParameter;
if (CommandParameter != null)
{
resolvedParameter = CommandParameter;
}
else if (Converter != null)
{
resolvedParameter = Converter.Convert(eventArgs, typeof(object), null, null);
}
else
{
resolvedParameter = eventArgs;
}
if (Command.CanExecute(resolvedParameter))
{
Command.Execute(resolvedParameter);
}
}
public static void OnEventNameChanged(BindableObject bindable, object oldValue, object newValue)
{
var behavior = (EventToCommandBehavior)bindable;
if (behavior.AssociatedObject == null)
{
return;
}
var oldEventName = (string)oldValue;
var newEventName = (string)newValue;
behavior.DeregisterEvent(oldEventName);
behavior.RegisterEvent(newEventName);
}
}
}
I hope someone could help me find a solution to this annoying issue. This whole problem does not exist on Android so I am kind of suprised that it throws these errors on iOS.
Cheers,
Luuk