2011-07-07 89 views
3

我有以下问题:NSManagedObject实施协议 - 由于@dynamic警告

随着我们的应用程序将被证明它在第一个版本的离线运行的潜在客户(由于依赖于后端是现在还没有完成),因此应用程序中显示的所有数据都将由CoreData从sqlite数据库中检索。由于我们希望避免以后的重构,我们决定将CoreData实体放在协议后面。服务将负责所有的数据检索并隐藏具有相应协议的实体。

在应用程序的更高版本中,UI开发人员只需将服务切换到后端人员,而不必因为遵守协议而更改其他代码。对于UI开发人员来说,如果实体将是NSManagedObjects或者仅仅是NSObjects,那么它们没有什么区别。

现在出现这个问题。 我们已经为我们的应用中的所有实体以及生成的适合这些协议的CoreData实体声明了协议(set-和get-Methods)。 CoreData对所有set/get-Methods(我们将在运行时从CoreData框架生成)使用@dynamic。

所有NSManagedObjects现在应该履行其相应的协议,但是编译器被给予了警告(因为@dynamic)的CoreData-对象不执行协议。

我只是想给你一个实体及相应的协议详细解释我的问题:

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开发。也许这是一个设计失败,而不是一个ObjC问题。我们想要坚持的是,在具有真实后端的高效版本中,UI开发人员不应该使用NSManageObject类来保留CoreData的东西。他只看到一个门面给了他一个API来与后面的层进行交互(First CoreData,后来的REST后端)。 UI开发人员应该只看到普通的VO或坚持使用协议(接口)。

我只想知道如何避免这些警告。所有提案都是受欢迎的;)

在此先感谢家伙!

回答

3

有一件事我可以建议蝙蝠:在Task.h定义的访问者应该与TaskCD接口@property声明的名字。相反的:

- (NSString*) getCategory; 

,你应该把它声明为:

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

或者,指定要在@property声明中的 “获取” 访问者的名称(在TaskCD。h):

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

另外恕我直言,与核心数据你使用动态生成访问器更好,而不是实现自己的。

0

首先,我要说的是,我在octy最好的解决方案达成一致很可能只是改变你的协议使用更标准的Objective-C的访问名称。

不过,我也想扔出去,你可以创建为每个生成CoreData对象category的选项,基本上他们的访问方法映射到访问者的名字,你想:

@interface TaskCD (Accessors) <Task> 

... 

@implementation TaskCD (Accessors) 

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

... 

这方式,你可以保留生成的文件(并且通常你可以重新生成它们)并仍然使用你自己的存取器方法名称。

这就是说,我仍然认为只要坚持使用Objective-C的默认存取器名称会更好。

0

还有另外一种方法可以实现:即使在你以后的REST版本中保存核心数据,并用实时数据分别使用NSManagedObjects来更新本地核心数据存储。在UI中使用核心数据实际上是一个好主意,因为您获得了很多好处(例如,在滚动时从核心数据中连续获取行)的桌面视图)