Тип свойства не соответствует типу доступа

Использование Xcode 6 Beta 4, ориентированного на iOS 8:

Я использую Core Data и Mogenerator вместе. Если вы не знакомы с "Mogen", пропустите снизу. Когда Mogen создает подкласс NSManagedObject для объекта, он делает это:

@interface MyEntityID : NSManagedObjectID {}
@end

@interface _MyEntity : NSManagedObject {}

- (MyEntityID*)objectID;

----------------------------------------------------------------------------

@implementation _MyEntity

- (KJMWorkoutID*)objectID {
    return (KJMWorkoutID*)[super objectID];
}

Это вроде удобно, я думаю. NSManagedObject имеет свойство objectID, все, что делает _MyEntity, переопределяет его getter, чтобы вернуть MyEntityID, чтобы мы могли определить его идентификатор специально для нашего _MyEntityClass.

Итак, вернемся к моему вопросу. Я хочу сравнить два идентификатора MyEntityID, установив, что они не равны:

if (![self.objectID isEqual:self.previousID])

Я получаю это предупреждение:

Type of property 'objectID' does not match type of accessor 'objectID'

Хорошо, я понимаю, что это свойство NSManagedObjectID, но мы вызываем метод доступа, который Mogen написал, который возвращает MyEnytityID. Даже это завершение кода распознает это.

Как он все еще видит тип свойства NSManagedObjectID для objectID объекта NSManagedObject? Должен ли я как-то замолчать предупреждение? Возможно, это всего лишь бета-версия Xcode 6? (это не происходит в Xcode 5)

Что такое Mogen:

Mogen - это просто полезный инструмент, который генерирует подклассы NSManagedObject для ваших объектов модели данных. Это похоже на то, что делает Xcode, но не стирает какой-либо пользовательский код, который вы пишете каждый раз при повторном создании подклассов, и он дает вам целую кучу хороших методов для создания новых объектов и т.д. Если нижний префикс класса prefixed имя вещь есть что-то новое для вас тоже, это просто способ, которым Mogen перестает переписывать любой пользовательский код, который вы пишете.

Ответы

Ответ 1

Проблема не связана с бета-версией Xcode 6, но из-за того, что объявление objectID изменилось в iOS 8. До iOS 7 оно было объявлено как метод экземпляра:

- (NSManagedObjectID *)objectID;

Как и в iOS 8/OS X 10.10, он объявляется как свойство только для чтения:

@property (nonatomic, readonly, strong) NSManagedObjectID *objectID;

Как объяснено в fooobar.com/questions/245506/..., вы можете переопределить метод экземпляра в подклассе с методом, имеющим более специализированное возвращаемое значение, в этом случае

- (MyEntityID *)objectID;

Но представляется проблематичным переопределить свойство с более специализированным возвратным значением (и это приведет к идентичному предупреждению с Xcode 5).

Следующее, похоже, работает как с "старыми", так и с "новыми" SDK: В "_MyEntity.h" замените

- (MyEntityID*)objectID;

по

@property (nonatomic, readonly, strong) MyEntityID *objectID;

и в "_MyEntity.m" удалите метод - (MyEntityID*)objectID и добавьте

@dynamic objectID;

Однако эти файлы всегда создаются Mogenerator, поэтому это не удовлетворяющее решению. Я бы рекомендовал подать отчет об ошибке пользователям Mogenerator, чтобы найти решение совместимый с SDK iOS 8/OS X 10.10.

Я не смог найти параметр компилятора для подавления этого предупреждения (он не отмечен "-W...", чтобы параметр "-Wno..." подавил его.

Как обходной путь, вы можете заменить self.objectID на [self objectID], что делает не вызывать предупреждения.

Ответ 2

@Martin R ответ правильный, но для тех, кто прибывает сюда с этого момента, Mogenerator обновлен до v1.28 и исправляет эту проблему.