How do you use a class method to distribute multiple shared instances of UIManagedDocument?

I have a helper class that distributes a common instance of UIManagedDocument. The idea is that the user requests a shared instance of UIManagedDocument for a specific file on disk. In this case, this is the main data warehouse. If a user requests a repository of master data located in a different path, I want to distribute an instance of UIManagedDocument for this file.

My question is: is it normal to create a new instance of UIManagedDocument and assign it to a static variable when the file changes? For instance:

+ (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 UIManagedDocument, so if several authors are stored in the kernel, I do not need to constantly synchronize the changes. However, since there are several data stores with a kernel on the disk, I cannot just allocate the same static variable each time.

Any ideas? I am absolutely fixated even on how to approach this design problem ... Any help is appreciated.

Thanks - Jake

+4
source share
2 answers

Well, if you are trying to do what I think you are trying to do: no, that will not work.

I assume that you want to keep sharedDocument for each unique file on disk requested independently of any other sharedDocuments . But your code will not do this, because every time a filename is passed, which is different from the last one passed to fileName, the link to the old UIManagedDocument is lost.

Imagine the following (far-fetched) scenario:

 UIManagedDocument *docA = [self sharedManagedDocumentForFile:@"fileA.txt"]; UIManagedDocument *docB = [self sharedManagedDocumentForFile:@"fileB.txt"]; UIManagedDocument *docA2 = [self sharedManagedDocumentForFile:@"fileA.txt"]; 

You expect docA and docA2 be the same UIManageDocument , but this will not happen because the middle line made your static variable forget the original managed document for file1.txt1 .

I would refuse to use a static variable. There are many other ways you could do this. A simple way would be to use NSMutableDictionary to map from file names to instances of UIManagedDocument . Something like that:

 + (UIManagedDocument *)sharedManagedDocumentForFile:(NSString *)fileName { //assuming we have an instance variable: NSMutableDictionary *docDictionary UIManagedDocument *doc = [docDictionary objectForKey:fileName]; if (!doc) { NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; url = [url URLByAppendingPathComponent:fileName]; // url is "<Documents Directory>/<vacationName>" doc = [[UIManagedDocument alloc] initWithFileURL:url]; [docDictionary setObject:doc forKey:fileName]; } return doc; } 

Update

Since sharedManagedDocumentForFile: is a class method, you cannot store docDictionary as an instance variable for your class, as you noticed. Instead, you can declare it in your .m file before implementing your class as follows:

 static NSMutableDictionary *docDictionary = nil; @implementation MyClass ... 

This actually gives a single docDictionary instance that exists outside of any instances of your class. Instances of your classes can still access it.

The static ensures that this docDictionary not obtainable outside the current compilation unit (i.e., the source file). For more information on statics and its various meanings, see Questions such as Difference between statics in C and statics in C ++?

+6
source

I get it. Use setObject, not addObject.

0
source

Source: https://habr.com/ru/post/1391553/


All Articles