Reputation: 2859
I have a Product
model with the header:
@interface Product : RLMObject <NSCopying,NSCoding>
{
}
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSString *thumbnailURL;
@property (nonatomic, strong) UIImage *thumbnail;
-(id)initWithInfo:(NSDictionary*)dictionary;
-(UIImage*)getThumbnail;
and implementation:
@implementation Product
-(id)initWithInfo:(NSDictionary*)dictionary
{
self = [self init];
if (self) {
_title = dictionary[@"title"];
_thumbnailURL = dictionary[@"thumbnailURL"];
_thumbnail = [self getThumbnail];
}
return self;
}
-(UIImage*)getThumbnail
{
if (_thumbnail) {
return _thumbnail;
}
//load image from cache
return [self loadImageFromCache];
}
Now, when I try to create a Product
object and insert it into Realm
, I always get the exception
[RLMStandalone_Product getThumbnail]: unrecognized selector sent to instance 0xcd848f0'
Now, I remove _thumbnail = [self getThumbnail];
and it works fine. But then I get another exception
[RLMStandalone_Product title]: unrecognized selector sent to instance 0xd06d5f0'
when I reload my view. I have created my Product
object in the main thread, so it should be fine to using its property and method, isn't it?
Any advice will be appreciated!
Upvotes: 1
Views: 2115
Reputation: 14409
Because Realm object properties are backed by the database rather than in-memory ivars, accessing those properties' ivars is not supported. We're currently clarifying our docs to convey this:
Please note that you can only use an object on the thread from which is was created or obtained, ivars shouldn't be accessed directly for any persisted properties, and that getters and setters for persisted properties cannot be overridden.
So to work with Realm, your model should look like this:
@interface Product : RLMObject
@property NSString *title;
@property NSString *thumbnailURL;
@property (nonatomic, strong) UIImage *thumbnail;
@end
@implementation Product
-(UIImage*)thumbnail
{
if (!_thumbnail) {
_thumbnail = [self loadImageFromCache];
}
return _thumbnail;
}
-(UIImage*)loadImageFromCache
{
// Load image from cache
return nil;
}
+(NSArray*)ignoredProperties
{
// Must ignore thumbnail because Realm can't persist UIImage properties
return @[@"thumbnail"];
}
@end
And usage of this model could look like this:
[[RLMRealm defaultRealm] transactionWithBlock:^{
// createInDefaultRealmWithObject: will populate object keypaths from NSDictionary keys and values
// i.e. title and thumbnailURL
[Product createInDefaultRealmWithObject:@{@"title": @"a", @"thumbnailURL": @"http://example.com/image.jpg"}];
}];
NSLog(@"first product's image: %@", [(Product *)[[Product allObjects] firstObject] thumbnail]);
Notice how initWithInfo
isn't necessary because RLMObject
already has initWithObject:
and createInDefaultRealmWithObject:
already do this.
Upvotes: 3