NSManagedObject, реализующий протокол - Предупреждения из-за @dynamic - PullRequest
3 голосов
/ 07 июля 2011

У меня следующая проблема:

Поскольку наше приложение будет показано потенциальным клиентам, оно должно работать в автономном режиме в первой версии (из-за зависимостей от серверной части, которая еще не завершена), и поэтому все данные, показанные в приложении, будут извлечены CoreData из базы данных sqlite. Поскольку мы хотим избежать последующего рефакторинга, мы решили поместить объекты CoreData за протоколы. Служба позаботится обо всем извлечении данных и скроет сущности с соответствующими протоколами.

В более поздней версии приложения разработчики пользовательского интерфейса просто переключат службу на серверную, и им не придется изменять оставшуюся часть кода из-за соблюдения протоколов. Для разработчика пользовательского интерфейса не имеет значения, будут ли сущности объектами NSManagedObject или просто объектами NSObject.

А теперь приходит проблема. Мы объявили протоколы (set- и get-Methods) для всех сущностей в нашем приложении и сгенерировали сущности CoreData, которые соответствуют этим протоколам. CoreData использует @dynamic для всех set / get-Methods (которые мы сгенерируем во время выполнения из инфраструктуры CoreData).

Все NSManagedObjects теперь должны реализовать свои соответствующие протоколы, но компилятор выдает предупреждения (из-за @dynamic), что CoreData-Object не реализует протокол.

Я просто хочу дать вам ОДИН объект и соответствующий протокол, чтобы подробно объяснить мою проблему:

TaskCD.h

@interface TaskCD : NSManagedObject<Task> {
@private
}
@property (nonatomic, retain) NSString * category;
@property (nonatomic, retain) NSNumber * frequency;
@property (nonatomic, retain) NSDate * validityEnd;
@property (nonatomic, retain) NSDate * validityStart;
@property (nonatomic, retain) NSNumber * periodicity;
@property (nonatomic, retain) NSString * descr;
@property (nonatomic, retain) NSNumber * selected;
@property (nonatomic, retain) NSSet* measurements;

@end

TaskCD.m

#import "TaskCD.h"
#import "MeasurementCD.h"

@implementation TaskCD
@dynamic category;
@dynamic frequency;
@dynamic validityEnd;
@dynamic validityStart;
@dynamic periodicity;
@dynamic descr;
@dynamic selected;
@dynamic measurements;

.... CoreData One-To-Many-stuff ....

@end

Task.h

@protocol Task <NSObject>

- (NSString*) getCategory;
- (void) setCategory:(NSString*) category;

- (NSNumber*) getFrequency;
- (void) setFrequency:(NSNumber*) frequency;

- (void) setValidityEnd:(NSDate *) date;
- (NSDate *) getValidityEnd;

- (void) setValidityStart:(NSDate *) date;
- (NSDate *) getValidityStart;

- (void) setPeriodicity:(NSNumber *) number;
- (NSNumber *) getPeriodicity;

- (void) setDescr:(NSString *) descr;
- (NSString *) getDescr;

- (void) setSelected:(NSNumber *) selected;
- (NSNumber *) getSelected;

- (void) setMeasurements:(NSSet*) measurements;
- (NSSet *) getMeasurements;

@end

У меня нет опыта работы с ObjC, и я работаю в Java Development. Возможно, это ошибка проектирования, а не проблема ObjC. Что мы определенно хотим придерживаться, так это то, что в продуктивной версии с реальным бэкендом разработчик пользовательского интерфейса НЕ должен работать с классами NSManageObject, чтобы не использовать материал CoreData. Он просто видит один фасад, предоставляющий ему API для взаимодействия со слоями позади (First CoreData. Позже REST backend). Разработчик пользовательского интерфейса должен видеть только простые VO или придерживаться протоколов (интерфейсов).

Я просто хочу знать, как избежать этих предупреждений. Все предложения приветствуются. ;)

Заранее спасибо, ребята !!

Ответы [ 3 ]

3 голосов
/ 07 июля 2011

Одна вещь, которую я могу предложить с самого начала: методы доступа, определенные в Task.h, должны соответствовать именам объявлений @property в интерфейсе TaskCD. Вместо:

- (NSString*) getCategory;

Вы должны объявить это как:

// this is the more common Obj-C naming convention
- (NSString*) category;

В качестве альтернативы укажите имя метода доступа get в объявлении @property (в TaskCD.h):

//meh... not so nice
@property (nonatomic, retain, getter=getCategory) NSString * category; 

Также ИМХО, с Core Data вам гораздо лучше использовать динамически генерируемые средства доступа, а не реализовывать свои собственные.

0 голосов
/ 30 августа 2011

есть другой подход, которому вы могли бы следовать: сохранить базовые данные даже в вашей более поздней версии REST и просто обновить локальное хранилище базовых данных живыми данными, соответственно, используя NSManagedObjects.использование базовых данных в пользовательском интерфейсе - хорошая идея, потому что вы получаете много преимуществ (например, подача табличных представлений, которые последовательно извлекают строки из базовых данных при прокрутке)

0 голосов
/ 07 июля 2011

Во-первых, я хочу сказать, что я согласен с octy в том, что наилучшим решением, вероятно, было бы просто изменить ваш протокол на использование более стандартных имен аксессоров Objective-C.

ОднакоЯ также хотел исключить опцию, что вы могли бы создать категорию для каждого из ваших сгенерированных объектов CoreData, который по существу сопоставляет их методы доступа с именами доступа, которые вы хотите:

@interface TaskCD (Accessors) <Task>

...

@implementation TaskCD (Accessors)

- (NSString *) getCategory {
     return [self category];
}

...

Таким образом, вы можете сохранить сгенерированные файлы (и сгенерировать их сколько угодно часто) и по-прежнему использовать собственные имена методов доступа.

При этом, я все же думаю, что было бы лучшепросто придерживаться имен аксессоров Objective-C по умолчанию.

...