【发布时间】:2015-03-05 00:11:23
【问题描述】:
我有一个名为 Mail 的基类,它本质上将充当一个抽象类,它具有确定邮件主题、正文、发件人等内容的具体子类。
让我们称一个这样的具体子类 NewsMail。
我之前在 Obj C 中设置过多态关系,但从未在 CoreData 中设置过。
似乎以下行需要在 xcdatamodel 中声明的类。以下行:
[NewsMail MR_createInContext:[NSManagedObjectContext MR_context]];
产生这个错误:
"NSInternalInconsistencyException", "+entityForName: could not locate an entity named 'NewsMail' in this model.
现在我可以通过在我的 xcdatamodel 中为我拥有的每个具体子类添加一个实体来解决这个问题,但这会在一段时间后变得笨拙。
建议?
更新
所以我有一个类别“邮件+类型”,我打算在其中配置具体类型:
#import "Mail.h"
#import "MailProtocol.h"
@interface Mail (Types)
+ (instancetype)newInstanceInContext:(NSManagedObjectContext*)context;
@end
@interface WelcomeMail : Mail<MailProtocol> @end
MailProtocol 将定义具体邮件应遵循的附加方法:
#import <Foundation/Foundation.h>
@protocol MailProtocol <NSObject>
- (NSString*)subjectKey;
- (NSString*)bodyKey;
- (void)build;
@end
(instancetype)newInstanceInContext:(NSManagedObjectContext*)context; 方法应该返回一个具体的类,但从父邮件类构建,如下面的答案中所指出的:
+ (instancetype)newInstanceInContext:(NSManagedObjectContext*)context
{
return [NSEntityDescription insertNewObjectForEntityForName:@"Mail" inManagedObjectContext:context];
}
我可以确认newInstanceInContext的正确具体类实现被执行了。
不幸的是,如果我尝试在 WelcomeMail 上运行构建,我会收到“无法识别的选择器”错误,因为它尝试在父级“邮件”类上运行它。
【问题讨论】:
-
I gave up。它是笨重的。可能有一种以编程方式编辑 MOM 的方法,但这同样丑陋。
-
在下面查看我的附加评论。这是我的错。显然,初始化程序会返回一个 Mail。我在下面建议了其他几种方法 - 但您可能会发现这些方法的开销或风险不仅仅是在 MOMD 中使用继承的实体。你有点反对 Liskov Substitution,因为你希望一个基类能够代替一个子类——但它真的不应该朝那个方向发展。 Mail 应该能够代替 ExpressMail - 但反过来不行。至少不是没有很多额外的开销。
-
嗯,也许我没有正确解释自己,但我真正想做的就是让 Mail 子类有自己的实现和属性配置,而无需在 MOM 中输入。如果我从问题中删除核心数据,那么它的行为很完美,但不幸的是我需要持久性......
标签: objective-c inheritance core-data polymorphism magicalrecord