【发布时间】:2016-10-16 14:38:21
【问题描述】:
我有一个名为Animal 的类,它是BaseEntity 的子类。我有一个名为CoreDataConversions 的协议,Animal 和BaseEntity 都有符合的类别。在协议中我定义了一个方法:
- (instancetype)initWithManagedObject:(NSManagedObject *)managedObject dataManager:(id<DataManager>)dataManager
BaseEntity 类别很好地实现了这一点。然后,因为Animal 是BaseEntity 的子类,所以我在动物类别中调用[super initWithManagedObject:managedObject dataManager:dataManager];。
我收到一条消息崩溃:
[Animal setDataManager:]无法识别的选择器发送到实例...
我在调用 super 时设置了一个断点并注销了以下内容:
po [self class] // Prints Animal
po [self superclass] // Prints BaseEntity
po [super class] // Prints Animal
po [super superclass] // Prints BaseEntity
那么:为什么Animal 类别的super 调用Animal,即使调用superclass 明确引用BaseEntity?
编辑:
这是导致崩溃的代码:
- (id)insertEntityForClass:(Class)class
{
if (![class conformsToProtocol:@protocol(CoreDataConversions)]) {
return nil;
}
// A class method defined in CoreDataConversions
NSString *entityName = [class coreDataEntityName];
// Insert core data entity
NSManagedObject *managedObject = [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:self.currentMainContext];
// Init with the managed object
id entity = [[class alloc] initWithManagedObject:managedObject dataManager:self];
return entity;
}
我有一个测试,它简单地调用Animal *animal = [dataManager insertEntityForClass:[Animal class]];,然后断言animal 的存在。
Animal 实现方法如下:
- (instancetype)initWithManagedObject:(NSManagedObject *)managedObject dataManager:(id<RHDataManager>)dataManager
{
self = [super initWithManagedObject:managedObject dataManager:dataManager];
if (self) {
// TODO
}
return self;
}
而BaseEntity 实现了这样的方法:
- (instancetype)initWithManagedObject:(id)managedObject dataManager:(id<RHDataManager>)dataManager
{
self = [super init];
if (self) {
self.dataManager = dataManager;
}
return self;
}
【问题讨论】:
-
你能把崩溃的代码贴出来,说明它所在的类。只是为了让问题更清楚。
-
@danh 刚刚添加了有关崩溃的代码
-
我可能很密集,但我在发布的代码中没有看到对
setDataManager的调用 -
是的,你是对的,事实证明它与属性声明有关。
-
请注意,这种方法很容易陷入未定义的行为。类别不能覆盖超类的方法,如果两个类别实现相同的方法,则未定义调用哪一个。您并没有完全这样做,所以这是定义行为的最边缘。类别的重点是添加独立的功能,而不是参与继承。当涉及的类别覆盖您在此处执行的方式时,它有很多方法会巧妙地(并且令人惊讶地)出错。
标签: objective-c categories superclass super