Realms.Exceptions.RealmInvalidObjectException Attempted to access detached row


#1

On refreshing UITableViews visible cells getting Realms.Exceptions.RealmInvalidObjectException Attempted to access detached row.

In my Xamarin.iOS app post login, we will check whether the same user (the previous user who had logged in last time) had logged in again or not? If the same user logs in again whatever data/models that exist in the Realm database is retained. In case a new user/different user logs in we are deleting all the data in the database and the navigation stack is reset. And post login we will sync data again. First API_1 is called to fetch a certain data (say realm_model_1) which is stored in the database and used to populate the table view. After completing API_1, another API (say API_2) is called to fetch additional data that belongs to another realm model (say realm_model_2), post which we will create a parent-child relationship between these two models by adding appropriate realm_model_1 data into a list in realm_model_2. After that, we will try to update all the visible cells in the table view. And when I call AssignmentsView.ReloadItems(AssignmentsView.IndexPathsForVisibleItems); am getting the RealmInvalidObjectException Attempted to access detached row.

Can someone point out the reason behind this exception in this scenario? All the API calls happen in a different Task and UI refresh actions happen after switching to main thread

[Edit]
Also observed that after logout and before login with a new user if i kill the app, launch the app again and login with the new user it wont crash.


#2

This error is typically thrown when you’re trying to access an object that has been deleted (e.g. on a background thread).


#3

Yeah I get that. But in my scenario I can see expected contents in my realm. I browsed through it using realm Studio. When I log in using a different user I delete all the contents in db, afterwards api fetch new data prior to updating the UI( which is visible in the db file). Hence am actually unable to decode the issue at hand. Ideally I shouldn’t get this issue if trying to access deleted object is the reason. And the same flow works absolutely fine when am installing the app for the first time and logging in. (api fetches the data and UI updated)


#4

So if I understand the flow correctly, it should go like this:

  1. You have some local data - display it in UI.
  2. You login a new user.
  3. They delete the local data and insert the new data fetched from the API.
  4. You tell the UI to update itself which throws that error.

If that’s the case, then my best guess would be that your UI component accesses the old objects for some reason before redrawing itself with the new data. We’ve seen some 3rd party XAML controls do that.


#5

before step-4 am setting the viewcontrollers again using setViewController so that should mean those are new UI components right?
Also observed that after logout and before login with a new user if i kill the app, launch the app again and login with the new user it wont crash.


#6

Maybe some databinding is happening? I have recently noticed same type of “errors” in one of my apps, that happened because of some databinding happening automatically by the framework.


#7

Any suggestion to clear such instances.


#8

The stacktrace in the exception should point to where the object access was attempted.


#9

I was trying to update an image in the visible cells, ie the code was like

UICollectionViewCell[] visibleCells = AssignmentsView.VisibleCells;
foreach (UICollectionViewCell cell in visibleCells)
{
if (cell is DashboardListCell)
{
((DashboardListCell)cell).SetCoverImage();
}
}

And the crash was from with in the SetCoverImage method of the DashboardListCell. And when I replace the updating the individual images in visible cells with reloadData for the whole CollectionView it is not crashing.

But even reloading individual item causes crash:

UICollectionViewCell[] visibleCells = AssignmentsView.VisibleCells;
foreach (UICollectionViewCell cell in visibleCells)
{
if (cell is DashboardListCell)
{
NSIndexPath path = AssignmentsView.IndexPathForCell(cell);
AssignmentsView.ReloadItems(new NSIndexPath[] { path });
}
}


#10

That doesnt seem to solve the problem. Other operations where DB objects are accessed throws the same exception. Cant really seem to get around this issue.


#11

What does the exception stacktrace say?