You cannot store a plain-old NSString in Core Data. It must be wrapped inside a NSManagedObject. Why? Because of the mandate above. An NSString is immutable. And Core Data wants to update the object you have in your hand, at the moment the context merges changes from another context. And it can’t change an immutable object. So it must wrap it inside something else, and change that.
This also has implications on threading. Why is it not safe to pass a NSManagedObject to background threads? Because that darn NSManagedObjectContext may mutate the thing at any time. So now threading becomes a nightmare. The fact is, the rules for NSManagedObject don’t follow the same rules you have for all other objects. Developers understand mutable vs immutable. Especially in objective-c where there are often 2 versions of a class, one mutable and one immutable. And developers understand the implications concerning threading: “Don’t be mutating something on one thread if it’s being used on another.” This is something we’ve lived with for a long time, and we’re quite adept at solving these problems. But NSManagedObject presents a whole new set of problems. We can’t just wrap one of these things in a lock, or only access it through a serial queue. Because NSManagedObjectContext isn’t going to follow our rules. It won’t play nicely, and so we’re forced to play entirely by its rules.
YapDatabase doesn’t use NSManagedObject, or any similar kind of silliness. You can store plain-old NSObjects. This includes your own NSObject subclasses, as well as the usual suspects such as NSString, NSNumber, UIColor, UIImage, etc. As long as the object can somehow be serialized & deserialized you’re good to go. This could be via NSCoding, or any other way you want such as JSON serialization. It’s completely configurable.
YapDatabase will never mutate any of your objects. Ever. This gives you complete control over your objects, and how & when you access and mutate them. You know, the way you’re used to dealing with objects.
YapDatabase looks really interesting. I skimmed the wiki to try to figure out the general architecture. It’s based on SQLite, which it uses as a collection-key-value store. In contrast to Core Data, it’s quasi-schemaless, although it does have some support for relationships.
It looks like there are four different mechanisms for selecting/filtering objects:
- By primary (string) key.
- Using a secondary SQLite index, which you explicitly set up and query using SQL fragments.
- Using Objective-C code on full in-memory objects that have been deserialized.
- Using SQLite’s FTS module.
Stay up-to-date by subscribing to the Comments RSS Feed for this post.