Reputation: 3269
Goal: Reduce memory footprint
My approach is to create single realm instance in AppDelegate class & then access that instead of creating a new variable each time.
AppDelegate
lazy var realm: Realm = {
let realm = try! Realm()
// Get our Realm file's parent directory
if let folderPath = realm.configuration.fileURL?.URLByDeletingLastPathComponent?.path{
// Disable file protection for this directory
do {
try NSFileManager.defaultManager().setAttributes([NSFileProtectionKey: NSFileProtectionNone],ofItemAtPath: folderPath)
}catch {
printDebug(error)
}
}
return realm
}()
UIViewController
var realm = (UIApplication.sharedApplication().delegate as! AppDelegate).realm
// Access/Modify realm object
try! self.realm.write{
location.imageFile = fileName
}
Questions
1. Will this help reduce memory usage?
2. What are the drawbacks?
Upvotes: 4
Views: 3267
Reputation: 8843
Questions
From my experience, getting the shared instance of realm and setting the URL is not an heavy task. Yet opening and closing a transaction some times is (depends on how often you do that, but at the end of the day most clients do not write heavily enough). So my answer for that is no, this will not help in memory usage. And by the way, did you profile your app to check were does your memory usage go to? Thats a good place to start at.
I have been using realm for some time now, and I've written 2 apps in production with Realm . Now what I'm about to say is not about memory usage, but about design.
A. Realm as you know is a data base. And you should not just access it from any random place in the application (not from a viewController), especially without wapping it with some class of yours (UsersDataBase class for example), and I'll explain. When objects in the DB start changing, you need to know who, were and from witch thread the writing is to DB. One place were you can check and debug. And when I'ts all over your application I't is very hard to debug.
B. Realm is not Thread safe. That means that you really want to know on witch thread realm is getting written too. If not, you will end up getting thread executions, and believe be, this is not a fun thing to deal with. Especily when realm does not help with the stack trace some times.
C. You are accessing realm on AppDelegate with "UIApplication.sharedApplication()". This is not best practice since you can't access "UIApplication.sharedApplication()" from diffrent contexts, for example App Extensions. And when you will want to add App extensions to your app, you will end up reWriting any place your using it.
Upvotes: 2
Reputation: 3635
Interesting question
1. In my opinion major drawback is that if you're going to use GCD with Realm. Remember that Realm is thread-safe so you can't use/modify Realm Object across threads/queues.
I handle Realm with Manager which is singleton. Maybe someone has better solution but this works just great.
class CouponManager: NSObject {
/// path for realm file
lazy private var realmURL: NSURL = {
let documentUrl = NSFileManager.defaultManager().URLsForDirectory(.CachesDirectory, inDomains: .UserDomainMask)[0]
let url = documentUrl.URLByAppendingPathComponent("coupons.realm")
return url
}()
lazy private var config:Realm.Configuration = {
return Realm.Configuration(
fileURL: self.realmURL,
inMemoryIdentifier: nil,
encryptionKey: "my65bitkey".dataUsingEncoding(NSUTF8StringEncoding),
readOnly: false,
schemaVersion: 1,
migrationBlock: nil,
deleteRealmIfMigrationNeeded: false,
objectTypes: nil)
}()
static let shared: CouponManager = CouponManager()
func save(coupons coupons:[Coupon]) {
let realm = try! Realm(configuration: config)
try! realm.write(){
realm.deleteAll()
realm.add(coupons)
}
}
func load() -> Results<Coupon> {
let realm = try! Realm(configuration: config)
return realm.objects(Coupon)
}
func deleteAll() {
let realm = try! Realm(configuration: config)
try! realm.write({
realm.deleteAll()
})
}
}
2. You shouldn't worry about memory when use Realm. As TiM (he works in Realm) said in this answer and you should instantiate Realm every time you need to.
Upvotes: 2