Как вы используете метод класса для распространения нескольких общих экземпляров UIManagedDocument? - PullRequest
4 голосов
/ 18 января 2012

У меня есть вспомогательный класс, который распространяет общий экземпляр UIManagedDocument.Идея состоит в том, что пользователь запрашивает общий экземпляр UIManagedDocument для определенного файла на диске.В данном случае это основное хранилище данных.Если пользователь запрашивает основное хранилище данных, расположенное по другому пути, я хочу распространить экземпляр UIManagedDocument для этого файла.

Мой вопрос: можно ли создать новый экземпляр UIManagedDocument и назначить его длястатическая переменная при изменении файла?Например:

+ (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;
}

По сути, я пытаюсь распространить только один экземпляр UIManagedDocument, поэтому в случае, когда в хранилище основных данных есть несколько устройств записи, мне не нужно постоянно хранитьизменения в синхронизации.Однако, поскольку на диске имеется несколько основных хранилищ данных, я не могу просто распределять одну и ту же статическую переменную каждый раз.

Есть идеи?Я абсолютно застрял даже на том, как подойти к этой проблеме дизайна ... Любая помощь приветствуется.

Спасибо - Джейк

Ответы [ 2 ]

6 голосов
/ 18 января 2012

Хорошо, если вы пытаетесь сделать то, что я думаю, вы пытаетесь сделать: нет, это не сработает.

Я предполагаю, что вы хотите сохранить sharedDocument для каждого уникального файла на запрошенном диске, независимо от любых других sharedDocuments существующих. Но ваш код этого не сделает, потому что каждый раз, когда передается fileName, который отличается от последнего, переданного в fileName, ссылка на старый UIManagedDocument теряется.

Представьте себе следующий (надуманный) сценарий:

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

Вы ожидаете, что docA и docA2 будут одинаковыми UIManageDocument, но этого не произойдет, потому что средняя строка заставила вашу статическую переменную забыть исходный управляемый документ для file1.txt1.

Я бы отказался от использования статической переменной. Есть много других способов сделать это. Простой способ - использовать NSMutableDictionary для сопоставления имен файлов с UIManagedDocument экземплярами. Примерно так:

+ (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;
}

Обновление

Поскольку sharedManagedDocumentForFile: является методом класса, вы не можете хранить docDictionary в качестве переменной экземпляра для своего класса, как вы заметили. Вместо этого вы можете объявить его в файле .m перед реализацией вашего класса следующим образом:

static NSMutableDictionary *docDictionary = nil;

@implementation MyClass ...

Это фактически дает один экземпляр docDictionary, который существует вне любых экземпляров вашего класса. Экземпляры ваших классов все еще могут получить к нему доступ.

Ключевое слово static гарантирует, что эта переменная docDictionary не будет доступна вне текущей единицы компиляции (то есть исходного файла). Для получения дополнительной информации о static и его различных значениях см. Такие вопросы, как Разница между static в C и static в C ++ ??

0 голосов
/ 16 апреля 2012

Я понял это.Используйте setObject, а не addObject.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...