I have a helper class that distributes a shared instance of UIManagedDocument. The idea is that the user requests the UIManagedDocument shared instance for a particular file on disk. In this case, it’s a core data store. If the user requests the core data store located at a different path I want to distribute an instance of UIManagedDocument for that file.
My question is: Is it ok to create a new instance of a UIManagedDocument and assign it to the static variable when the file changes? For example:
+ (UIManagedDocument *)sharedManagedDocumentForFile:(NSString *)fileName
{
static UIManagedDocument *sharedDocument = nil;
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:fileName];
// url is "<Documents Directory>/<vacationName>"
// Create the shared instance lazily upon the first request.
if (sharedDocument == nil) {
sharedDocument = [[UIManagedDocument alloc] initWithFileURL:url];
}
if (sharedDocument.fileURL != url) {
UIManagedDocument *newDocument = [[UIManagedDocument alloc] initWithFileURL:url];
sharedDocument = newDocument;
}
return sharedDocument;
}
Basically what I’m trying to do is distribute only one instance of a UIManagedDocument so in the event there are multiple writers to the core data store I don’t have to constantly keep the changes in sync. However, since there are multiple core data stores on disk I can’t just distribute the same static variable every time.
Any ideas? I’m absolutely stuck on even how to approach this design problem… Any help is appreciated.
Thanks – Jake
Ok, if you’re trying to do what I think you’re trying to do: no, this won’t work.
I’m assuming you want to persist a
sharedDocumentfor each unique file on disk requested, independently of any othersharedDocumentsin existence. But your code won’t do that, because every time a fileName is passed in which is different from the last passed in fileName, the reference to the oldUIManagedDocumentis lost.Imagine the following (contrived) scenario:
You’re expecting
docAanddocA2to be the sameUIManageDocumentbut that won’t happen, because the middle line caused your static variable to forget the original managed document forfile1.txt1.I’d abandon the use of the static variable. There’s many other ways you could do this. A simple way would be to use an
NSMutableDictionaryto map from filenames toUIManagedDocumentinstances. Something like this:Update
Because
sharedManagedDocumentForFile:is a class method, you can’t storedocDictionaryas an instance variable for your class, as you note. Instead, you can declare it in your.mfile before your class implementation like so:This in effect gives a single
docDictionaryinstance that exists outside of any instances of your class. Instances of your classes can still access it though.The
statickeyword ensures that thisdocDictionaryvariable can’t be accessed outside the current compilation unit (i.e. source file). For more info on static and its many different meanings, see questions such as Difference between static in C and static in C++??