#objective-c #inheritance #core-data
#objective-c #наследование #ядро-данные
Вопрос:
Я пытаюсь создать подкласс некоторых базовых классов данных. У меня есть следующие классы:
Базовый класс данных:
@interface CDExplanatoryMaterial : NSManagedObject
@property (nonatomic, retain) NSString * document;
@property (nonatomic, retain) NSString * id;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * pageNumber;
@property (nonatomic, retain) NSNumber * realPageNumber;
@property (nonatomic, retain) NSString * url;
@end
Протокол класса бизнес-логики:
@protocol BLDataClass <NSObject>
- (NSArray*)favouriteInGroups;
@property (nonatomic, readonly, retain) NSString* type;
@property (nonatomic, readonly, retain) NSArray* inFavouriteGroups;
- (void)addAddToFavouriteGroup: (NSString*) groupName;
- (void)removeFromFavouriteGroup: (NSString*) groupName;
- (void)addToHistory;
@end
Интерфейс для BLExplanatoryMaterial:
@interface BLExplanatoryMaterial : CDExplanatoryMaterial <BLDataClass>
Я получаю данные следующим образом:
(NSMutableArray*) explanatoryMaterials {
NSMutableArray* results = [[NSMutableArray alloc] init];
for(CDExplanatoryMaterial *item in [Helper fetchDataObjectsOfType:@"CDExplanatoryMaterial"])
{
[results addObject: (BLExplanatoryMaterial*)item];
}
return results;
}
Вспомогательный класс выглядит следующим образом:
@implementation Helper
(NSArray*) fetchDataObjectsOfType:(NSString *)type {
DataManager* manager = [DataManager sharedInstance];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:type inManagedObjectContext:manager.mainObjectContext];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *fetchedObjects = [manager.mainObjectContext executeFetchRequest:fetchRequest error:amp;error];
return fetchedObjects;
}
@end
Проблема, с которой я сталкиваюсь, заключается в том, что массив fetchedObjects в fetchDataObjectsOfType и массив результатов в explanatoryMaterials содержат только объекты NSManagedObject. Я бы ожидал, что извлеченные объекты будут содержать объекты CDExplanatoryMaterial, а результаты будут содержать BLExplanatoryMaterial. Мне нужно, чтобы конечным результатом были объекты BLExplanatoryMaterial, иначе я не смогу использовать ни один из моих методов экземпляра, каков наилучший способ сделать это?
Спасибо,
Джо
Редактировать:
Просто чтобы уточнить, это следующий код, который завершается с ошибкой, потому что expMat является NSManagedObject и не поддерживает метод addToFavouriteGroup.
NSMutableArray* expMats = [Data explanatoryMaterials];
BLExplanatoryMaterial* expMat = (BLExplanatoryMaterial*) [expMats objectAtIndex:0];
[((BLExplanatoryMaterial*)expMat) addToFavouriteGroup:@"Test Group"]
Одна вещь, о которой я забыл упомянуть, это то, что весь код в моем исходном сообщении находится в статической библиотеке. Код, опубликованный в этой правке, находится в проекте приложения для IOS. Я не уверен, имеет ли это значение. Все классы в статической библиотеке помечены как общедоступные.
Ответ №1:
Вам необходимо указать BLExplanatoryMaterial
в качестве класса для объекта в вашей модели управляемого объекта. Это подскажет Core Data создавать экземпляры объектов этого класса вместо NSManagedObject
.
Комментарии:
1. Я только что заглянул в раздел Конфигурации -> Бит по умолчанию, и там говорится, что CDExplanatoryMaterial является классом для объекта CDExplanatoryMaterial. Я думаю, это выглядит правильно? Я попробую это изменить.
2. Изменение класса не имеет никакого значения.
3. Можете ли вы переопределить
-awakeFromFetch
в своемNSManagedObject
подклассе, чтобы посмотреть, вызывается ли он при извлечении объекта из хранилища?
Ответ №2:
Спасибо за всю помощь. Оказывается, поскольку классы core data находились в отдельной статической библиотеке, они не были встроены в основной пакет. Чтобы обойти это, я разделил их на подклассы в моем основном приложении, а затем указал файл core data на эти подклассы.