Hey, i'm having trouble figuring out why my app is crashing. It works fine on Android, but on iOS I get
System.NullReferenceException
Object reference not set to an instance of an object
I attached my iOS device crash logs. Here is part of it...
...
Exception Type: EXC_BAD_ACCESS (SIGABRT)
Exception Subtype: KERN_INVALID_ADDRESS at 0x00000000
...
13 StreetSupervisorIOS 0x016028fc handle_signal_exception (exceptions-arm.c:530)
14 StreetSupervisorIOS 0x0123a6d4 Xamarin_Forms_Platform_iOS_VisualElementPackager_HandleChildRemoved_object_Xamarin_Forms_ElementEventArgs + 268
...
Here are snippets of my code. It crashes on layout.Children.Clear(), but not every time. Neither layout nor layout.Children is null, but I still get the NullReferenceException...
// UserList is a StackLayout in my xaml containted within UserScrollList (ScrollView)
// UserRows contains the RelativeLayouts that I will put in the UserList
UserRows = new Dictionary<int, RelativeLayout>();
private void ClearUserRows()
{
Log.Debug("Clearing UserView rows");
foreach (RelativeLayout layout in UserRows.Values)
{
layout.Children.Clear (); //CRASHES HERE
}
UserRows.Clear();
UserList.Children.Clear();
this.UserListScroll.IsClippedToBounds = false;
this.UserListScroll.IsClippedToBounds = true;
}
public void CreateUserRows()
{
ClearUserRows ();
List<UserEntry> sortedUsers = ViewModel.OnlineUsers.OrderBy(ue => ue.Fullname).ToList();
// Remove the UserList temporarily so the layout doesn't recalculate a million times during the loop. It was taking a long time before
this.UserListScroll.Content = null;
foreach (UserEntry ue in sortedUsers)
{
Label name = new Label ();
name.HorizontalOptions = LayoutOptions.StartAndExpand;
name.Text = ue.Fullname;
name.YAlign = TextAlignment.Center;
name.TextColor = (Color)this.Resources ["TextColor"];
name.Font = Font.SystemFontOfSize (20);
Image chkBackground = new Image ();
chkBackground.HorizontalOptions = LayoutOptions.End;
chkBackground.IsVisible = true;
chkBackground.Aspect = Aspect.Fill;
if(ue.Selected)
{
chkBackground.Source = Device.OnPlatform (
iOS: CHECKBOX_CHECKED,
Android: CHECKBOX_CHECKED,
WinPhone: CHECKBOX_CHECKED);
}else
{
chkBackground.Source = Device.OnPlatform (
iOS: CHECKBOX_EMPTY,
Android: CHECKBOX_EMPTY,
WinPhone: CHECKBOX_EMPTY);
}
BetterButton clickDetector = new BetterButton ();
clickDetector.Opacity = 1;
clickDetector.BackgroundColor = Color.Transparent;
clickDetector.Text = "";
clickDetector.CommandParameter = ue.EmployeeID;
clickDetector.Command = ViewModel.UserClicked;
RelativeLayout layout = new RelativeLayout ();
layout.HorizontalOptions = LayoutOptions.StartAndExpand;
layout.HeightRequest = 40;
layout.WidthRequest = 1000000000;
layout.Children.Add (name,
Constraint.Constant (15),
Constraint.Constant (0),
Constraint.RelativeToParent ((parent) => {
return parent.Width * 0.8;
}),
Constraint.RelativeToParent ((parent) => {
return parent.Height;
}));
layout.Children.Add (chkBackground,
Constraint.RelativeToParent ((parentView) => {
return parentView.Width - 30;
}),
Constraint.RelativeToParent ((parentView) => {
return (parentView.Height * 0.5) - 11;
}),
Constraint.Constant (22),
Constraint.Constant (22));
layout.Children.Add (clickDetector,
Constraint.Constant (-5),
Constraint.Constant (-5),
Constraint.RelativeToParent ((parent) => {
return parent.Width + 10;
}),
Constraint.RelativeToParent ((parent) => {
return parent.Height + 10;
}));
if(!UserRows.ContainsKey(ue.EmployeeID))
UserRows.Add (ue.EmployeeID, layout);
this.UserList.Children.Add (layout);
}
this.UserListScroll.Content = this.UserList;
this.UserListScroll.IsClippedToBounds = false;
this.UserListScroll.IsClippedToBounds = true;
}
It is probably worth noting that the crash is relatively new. Before I added these lines
// Remove the UserList temporarily so the layout doesn't recalculate a million times during the loop. It was taking a long time before
this.UserListScroll.Content = null;
//loop
this.UserListScroll.Content = this.UserList;
it worked fine. The reason I remove the list and put it back is that the list was taking very long to load on iOS. When I orphan the StackLayout from its parent ScrollView, the layout doesn't get recalculated a lot and the list loads faster.
Any help would be appreciated. Thanks in advance!