2016-10-16 21 views
-1

У меня есть класс под названием Animal, который является подклассом BaseEntity. У меня есть протокол под названием CoreDataConversions, который и Animal и BaseEntity имеют категории, соответствующие. В протоколе у ​​меня есть метод, определенный:Вызов `super` в категории Objective-C

- (instancetype)initWithManagedObject:(NSManagedObject *)managedObject dataManager:(id<DataManager>)dataManager

BaseEntity категория реализует этот штраф. Тогда, поскольку Animal является подклассом BaseEntity, я звоню [super initWithManagedObject:managedObject dataManager:dataManager]; в категории животных.

я получаю сбой с сообщением:

[Animal setDataManager:] непризнанный селектор послал к экземпляру ...

я поставил точку останова на вызов супер и логает следующее:

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?

EDIT:

Вот код, который вызывает сбой:

- (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; 
} 
+0

Можете ли вы опубликовать код вокруг сбоя, указав класс, в котором он находится. Просто чтобы сделать вопрос понятнее. – danh

+0

@danh просто добавил код вокруг сбоя –

+1

Я мог быть плотным, но я не вижу вызова 'setDataManager' в опубликованном коде – danh

ответ

0

Оказывается, это на самом деле делать с декларациями собственности. У меня были readonly свойства, то есть @property (nonatomic, strong, readonly) id<DataManager> dataManager;, определенные в исходном классе.

в категории Я пересмотрел свойство так:

@property (nonatomic, strong) id<DataManager> dataManager;

Катастрофа была вызвана тем, что не было никакого сеттер установить в Animal для dataManager, потому что он все еще читал его как readonly.