Problem with creating multiple YapDatabase Objects

162 views
Skip to first unread message

Brendan Farmer

unread,
Mar 20, 2015, 12:26:06 PM3/20/15
to yapda...@googlegroups.com
Hi, so I'm relatively new to iOS development, but I've really enjoyed working with YapDB thus far. I'm running into a slight problem that I can't seem to fix: in my app, users need to have separate databases for privacy reasons, and I'm having trouble creating a new yapdatabase object for the case when a user logs out and another user logs back in. Essentially, I have a StorageManager singleton, and on login, I want to set the _database property of the singleton to the new database (just the user's username appended on the default file path). The trouble is, whenever there already exists a YapDatabase object for the property _database, all future attempts to create a YapDatabase object are null. Here's some code for the storage manager:


And where it's being called in my login method:


When [[KStorageManager sharedManager] refreshDatabaseAndConnection] is removed from the login action, it works, even though that same method is called when a new StorageManager is init-ed. If anyone can point me toward what I'm doing wrong, or suggest a better method to handle changing singleton properties, I would greatly appreciate it!!

Thanks,
-Brendan

Robbie Hanson

unread,
Mar 20, 2015, 8:52:07 PM3/20/15
to yapda...@googlegroups.com
all future attempts to create a YapDatabase object are null

You shouldn’t have any problem creating multiple YapDatabase objects IF they represent different filePaths.
However, if you attempt to init a YapDatabase object with filePath X, and there is already a YapDatabase instance for filePath X, then the init will fail, and return nil.

You may want to set a breakpoint in YapDatabase’s init method here:

// Ensure there is only a single database instance per file.

// However, clients may create as many connections as desired.

if (![YapDatabaseManager registerDatabaseForPath:path])

{

YDBLogError(@"Only a single database instance is allowed per file. "

            @"For concurrency you create multiple connections from a single database instance.");

return nil;

}


Let me know if it’s another issue.

-Robbie Hanson


--
You received this message because you are subscribed to the Google Groups "YapDatabase" group.
To unsubscribe from this group and stop receiving emails from it, send an email to yapdatabase...@googlegroups.com.
To post to this group, send email to yapda...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Brendan Farmer

unread,
Mar 20, 2015, 11:52:45 PM3/20/15
to yapda...@googlegroups.com
Breakpoint confirms that's the issue. This might just highlight my ignorance when it comes to ARC, but how do I explicitly dealloc that YapDatabase object when a user logs out? For reference, here's my storage manager, like I said - it has a _database property that's instantiated on load, and which I had set to nil on logout. Apologies if this is a waste of your time, but it would be great to figure this out.


Thanks,
-Brendan

Robbie Hanson

unread,
Mar 21, 2015, 1:38:58 PM3/21/15
to yapda...@googlegroups.com
> how do I explicitly dealloc that YapDatabase object when a user logs out?

No worries, this is question I’ve gotten a few times. And it can be a bit tricky because of the architecture.

The YapDatabase class itself is rather sparse. You’ll notice it’s really nothing more than a placeholder to get connections. It basically just stores the configuration info (databasePath, blocks, options, etc). All the action takes place elsewhere. And it’s YapDatabaseConnection that actually opens up a “connection” to the database file. (a sqlite instance) Thus YapDatabaseConnection retains YapDatabase. Meaning you cannot deallocate a YapDatabase instance if you still have YapDatabaseConnection instances running around.

This might seem odd at first, but it also mimics the file system. You generally cannot delete a file that’s open (in use) by a process. In the same way, you cannot deallocate a YapDatabase instance that’s in use by a YapDatabaseConnection.

Long story short: you’ll need to nil your databaseConnection properties (probably sitting in viewControllers)

-Robbie Hanson


Koushik Ravi Kumar

unread,
Jan 12, 2017, 8:20:46 AM1/12/17
to YapDatabase
Hey Robbie,

Thank you so much for this. Just to confirm, it is best to set the connections to nil in the dealloc method of the viewcontrollers, correct?

Robbie Hanson

unread,
Jan 12, 2017, 5:48:36 PM1/12/17
to yapda...@googlegroups.com
I’ll break the question down into 2 separate questions:

1. I want to explicitly deallocate a YapDatabase instance, while my ViewController is still alive. And my ViewController has a reference to a YapDatabaseConnection instance. How do I accomplish this ?

You’l need to explicitly set your databaseConnection instance to nil. Because the YapDatabase instance cannot be deallocated while there are YapDatabaseConnection instances still around.

(See also explanation of why, from earlier answer.)

2. Do I have to do anything special when my ViewController deallocates (concerning YapDatabase).

Assuming Swift, or modern Obj-C with ARC:

Nope. During the deallocation process, the runtime (compiler?) will automatically send a ‘release’ to all the view’s instance variables / properties. So if the ViewController is the only one holding a reference to the YapDatabaseConnection instance, it will deallocate at this time.

In other words, the YapDatabaseConnection instance will get deallocated automatically, just like any other instance variable of the ViewController.

-Robbie Hanson
Reply all
Reply to author
Forward
0 new messages