Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to make copy of Realm object?

Tags:

ios

realm

I want to refresh the Realm database in the background thread like this: (Because I have got fresh data from Webservice)

 RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
[realm deleteAllObjects]; // !!
[Pubs createOrUpdateInRealm:[RLMRealm defaultRealm] withJSONArray:data];
[realm commitWriteTransaction];

Problem is, that meanwhile I delete & renew the objects in Realm db, user can open some Detail ViewController pointing to some Realm object (Pubs) which has been deleted meanwhile so the exception is thrown.

I don't see any solution for this, except always when I would like to access the Realm object from Detail controller or its property I would need to always do something like this:

(That means always get Realm object, but that can probably fail too)

pub = [Pubs objectsWhere:[NSString stringWithFormat: @"pubId = %lu", (long)_selectedPubId]].firstObject;

But I am not using this solution. I am thinking best would be if I could call in Detail view controller something like this:

pub = [Pubs objectsWhere:[NSString stringWithFormat: @"pubId = %lu", (long)_selectedPubId]].firstObject;
pub = [pub safeCopy];

So the PubRealmObject can be meanwhile deleted, but the pub object will solo exist in the memory (only for the purpose to access its data properties).

So did someone try something similar?

Or maybe even using some iOS SDK way like this?

I need to only access the data properties as I say, not operate with realm object methods like delete or update the object in the db.

Btw I tried to call the update of Realm db in the main thread, but the problem is it takes like 5-7 seconds (only 1000 JSON objects) so it lags the application. That's why I am thinking the background update & safe copying of object could be better.

But I am thinking that it can fail even while copying the object, so what is the solution for this? (background update vs safe access of Realm object)

like image 377
luky Avatar asked Dec 14 '22 04:12

luky


1 Answers

It's usually not a good design pattern to have a view controller relying on a data model that can be deleted out from underneath it. It's possible to check if a Realm object has been deleted to avoid exceptions by checking its object.invalidated property.

In any case, to create a detached copy of a Realm object, all you need to do is:

RLMObject *copiedObject = [[RLMObject alloc] initWithValue:object];

This will make a copy of the object, but it will not be inserted into any Realm instance. Please note that if the object links to any other Realm objects, these will not be copied as well; the new object will just be pointing at the existing copies.

But I still feel like I need to mention that you could probably just make your implementation of updating Realm from your web service a bit smarter to avoid the need to do this.

If your objects implement a primary key, then when you call createOrUpdateInRealm, the existing objects will be updated with the new values.

Good luck!

like image 174
TiM Avatar answered Dec 29 '22 11:12

TiM