theDuncs
theDuncs

Reputation: 4843

ObjC Realm Threading issue

I have a Realm object (LFEMemory) which has a publish method.

When I call the publish method, I have to upload an image to AWS and then update the object with the URL returned by Amazon.

The problem is that when the block returns from AWS, my self LFEMemory object is no longer thread-safe. (In fact, it usually is during the usual running of the app but never if I'm using an App Extension).

I could fix this by removing the publish method from the realm object, and handling it in a controller object, which can fetch a new realm object on the new thread. But that means I need to create new realms everytime I call a block, which surely isn't a good practise.

How do most people handle this situation?

- (void)publishWithBlock:(ResultBlock)block {

    FileUploadManager *manager = [[FileUploadManager alloc] init];
    [manager uploadWithSuccess:^(NSString *filename) {

        //self is no longer thread-safe and will cause a crash
        self.media.path = filename;

    } failure:^(NSError *error) {
        block(NO, error);
    };
}

Upvotes: 0

Views: 121

Answers (1)

Marin Todorov
Marin Todorov

Reputation: 6397

You have various options you can explore:

1) if your object has a primary key (string or a number) you can store the id as a constant inside the method and use it to fetch back the object from any thread by using [Realm objectOfType:forPrimaryKey:]. docs

Don't be afraid to get a new realm from the different thread if that's what you need to do - that does not create "another" Realm or duplicate your file.

2) if you don't have a primary key you can simply create self.media on the main thread and whenever the upload has finished, switch again to the main queue and modify your object there - modifying a property or two on a Realm object will not harm at all your performance on the main thread.

Further - if you have access to your object (as in self.media) it already gives you access to the original Realm used to create / read the object via its realm property docs

Still - I'd go with using the primary key of the object to re-fetch a reference to the object I need if in doubt.

Upvotes: 1

Related Questions