Тип возвращаемого значения executeFetchRequest изменился, когда модель помещена в статическую библиотеку - PullRequest
0 голосов
/ 13 февраля 2011

Надеюсь, это будет легко для тех, у кого больше опыта работы с Core Data и XCode, чем у меня.

Я пытаюсь переместить слой модели приложения iOS в статическую библиотеку, чтобыможет использовать его повторно.Я успешно отделил код и собрал / запустил приложение.К сожалению, я сталкиваюсь со специфической проблемой.

Рассмотрим следующий фрагмент кода:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

NSEntityDescription *entityDescription = [NSEntityDescription entityForName:entityName inManagedObjectContext:context];
[fetchRequest setEntity:entityDescription];
fetchRequest.includesSubentities = NO;
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"UID = %@", uID]];
fetchArray = [context executeFetchRequest:fetchRequest error:&fetchError];
id obj = [fetchArray objectAtIndex:0];
NSString *fetchArrayIndexZeroEntityName = [[obj entity] name];

Когда все находится в одном проекте xcode: тип указателя obj в соответствии с всплывающим пузырем отладчика xcodeравно MyCustomCoreDataClassName и

fetchArrayIndexZeroEntityName = @"MyCustomCoreDataClassName"

После перемещения базовой модели данных в статическую библиотеку: тип указателя obj в соответствии с всплывающим подсказком отладчика xcode равен NSManagedObject и

fetchArrayIndexZeroEntityName = @"MyCustomCoreDataClassName"

Позже в моем коде я делаю следующий вызов:

[obj isKindOfClass:[MyCustomCoreDataClassName class]]

Когда все в одном проекте xcode, вышеуказанный вызов возвращает YES.После того, как я переместил базовую модель данных в статическую библиотеку, приведенный выше вызов возвращает NO.

Это поведение, очевидно, имеет довольно печальные последствия для моего приложения.Есть мысли о том, что может быть не так и как это исправить?Вполне возможно, что я связал эти проекты вместе неполно или неправильно, даже если он компилируется без ошибок и запускается, по крайней мере, достаточно, чтобы раскрыть вышесказанное.

Спасибо, Эндрю

1 Ответ

0 голосов
/ 13 февраля 2011

В зависимости от того, как вы настраиваете свой базовый стек данных, прямо в его духе, убедитесь, что когда вы читаете NSManagedObjectModel (s), которые обычно создаются из NSBundle, у вас есть несколько действительных сущностей.Установите точку останова в своем проекте, где возвращается модель, а затем в вызове отладчика:

po [[managedObjectModel entitiesByName] allKeys]

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

Вот что я сделал, чтобы обойти это.В своем проекте статической библиотеки (или если ваша статическая библиотека - просто еще одна цель в вашем основном проекте), создайте новую цель NSBundle.Добавьте базовую модель данных и любые модели отображения, которые у вас есть, к этой цели.Затем добавьте его в качестве зависимости к вашей цели статической библиотеки и цели приложения.В своей основной цели приложения добавьте этот новый пакет в фазу сборки Copy Bundle Resources.

Затем в вашем стеке базовых данных вам просто нужно найти все пакеты для поиска моделей.У меня есть код, подобный следующему:

/**
 Creates, retains, and returns the managed object model for the application 
 by merging all of the models found in the application bundle.
 */

- (NSManagedObjectModel *)managedObjectModel {

    if (managedObjectModel) return managedObjectModel;

    // Get all the bundles including ones nested inside the main bundle
    NSMutableSet *allBundles = [NSMutableSet set];
    NSMutableSet *newBundles = [NSMutableSet set];
    NSUInteger numberOfBundles = 0;
    [allBundles addObject:[NSBundle mainBundle]];

    while (numberOfBundles < [allBundles count]) {
        // Look for nested bundles
        for(NSBundle *bundle in allBundles) {
            NSArray *morePaths = [NSBundle pathsForResourcesOfType:@".bundle" inDirectory:[bundle bundlePath]];
            if([morePaths count] > 0) {
                for(NSString *bundlePath in morePaths) {
                    if(![allBundles containsObject:bundlePath])
                        [newBundles addObject:[NSBundle bundleWithPath:bundlePath]];                    
                }
            }
        }
        // Add the new bundles
        [allBundles unionSet:newBundles];
        numberOfBundles = [allBundles count];
    }

    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:[allBundles allObjects]] retain];

    if (managedObjectModel) return managedObjectModel;  

    return nil;
}

Обратите внимание, что приведенный выше код не должен знать, как вы назвали свою модель.У меня есть эта функция в одноэлементном классе, который также создает постоянный координатор хранилища и возвращает MOC.Так эффективно, как только вы это сделали, у вас есть полностью общее использование в любом месте стека базовых данных, который вы можете создать из любого места в вашем приложении.

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

...