-
Notifications
You must be signed in to change notification settings - Fork 363
MyDatabaseObject
Tips and tricks for making YapDatabase even easier.
YapDatabase itself is object agnostic. That is, unlike many other databases, it doesn't force you to use a base class. The object policy is simply: if you can serialize/deserialize it, then YapDatabase can use it.
More information about this can be found in the Storing Objects wiki page. In fact, it even mentions several 3rd party frameworks that you might wish to use as your base class:
Ultimately, you decide what the best object setup is for your app. And YapDatabase can accommodate you.
What follows are some tips & tricks (related to model objects) that we've accumulated over the years. We've combined them all together, and placed them into a sample project that's available within the repository.
As we review the neat little tricks this class contains, keep in mind that you're welcome to copy any of the code from this class. You can copy the whole thing, and rename it to match your project. Or just copy the bits & pieces you want. (Hey, maybe you'd like to use some of this stuff for non-YapDatabase purposes. That's OK too!)
Immutable classes are great! You can pass them around between threads, and never worry about stepping on toes. This is why Apple's Foundation classes often have both immutable & mutable variants. (NSString & NSMutableString, NSArray & NSMutableArray, NSDictionary & NSMutableDictionary ...) Being able to take an object, and make an immutable copy is incredibly useful. (P.S. calling copy
on an immutable object generally returns self
. So it's no more expensive than a retain
.)
However, how often do you make both immutable & mutable variants for your own classes ?!? The answer for most people is never. And why not? Probably because it would be a big pain in the rear! Not only that, but it could quick complicate your ability to subclass your model objects. (Think about subclassing MyCar when MyMutableCar is already a subclass...)
Luckily we can use KVO tricks to enforce immutability when we want it. Here's the API:
@property (nonatomic, readonly) BOOL isImmutable;
- (void)makeImmutable;
- (instancetype)mutableCopy;
- (instancetype)immutableCopy;
- (NSException *)immutableExceptionForKey:(NSString *)key;
And here's how easy it is to use:
#import "MyDatabaseObject.h"
@interface Car : MyDatabaseObject
@property (nonatomic, copy, readwrite) NSString *make;
@property (nonatomic, copy, readwrite) NSString *model;
@end
@implementation Car
@synthesize make;
@synthesize model;
- (id)copyWithZone:(NSZone *)zone
{
Car *copy = [super copyWithZone:zone];
copy->make = make;
copy->model = model;
return copy;
}
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
Car *car = [[Car alloc] init];
car.make = @"Tesla";
car.model = @"Model S";
[car makeImmutable];
car.make = @"Ford"; // Throws exception: Attempting to mutate immutable object...
Car *car2 = [car mutableCopy];
car2.model = @"Model X"; // No problem
}