Objective-C: «предупреждение: тип свойства« владелец »не соответствует типу свойства протокола PieceModel» - PullRequest
1 голос
/ 18 августа 2010

Я получаю это предупреждение. Я пытаюсь создать семейство классов и параллельное семейство протоколов. Класс Piece имеет следующее объявление:

@interface Piece : NSManagedObject <PieceModel>
{
}

...

@property (nonatomic, retain) Player *owner;

...

@end

PieceModel имеет это

@protocol PieceModel <NSObject>

...

@property (readonly, nonatomic, retain) id <PlayerModel> owner;

@end

И конечно:

@interface Player : NSManagedObject <PlayerModel> { ...

Мне кажется, все это должно быть абсолютно безопасно. Пользователи протоколов видят, что то, что соответствует протоколу PieceModel, имеет владельца, который должен соответствовать протоколу PlayerModel. Фактически каждый экземпляр класса Piece возвращает экземпляр Player для свойства owner, что соответствует протоколу PlayerModel. Я понимаю, почему есть такое предупреждение. Было бы небезопасно пытаться присвоить любой объект, который соответствует PlayerModel, владельцу, поскольку он может не принадлежать классу Player, но в этом случае это не проблема, поскольку свойство объявляется для протокола только для чтения.

Обратите внимание, что я также объявил свойство как retain, которое, если я не ошибаюсь, не имеет смысла для свойства только для чтения, но я также получил другое предупреждение о несоответствии между протоколом и классом, если я этого не сделал. По крайней мере, компилятор не жалуется, что одно свойство доступно только для чтения, а другое - нет.

Я знаю, что мог бы просто объявить свойство класса как возвращающее id <PlayerModel>, но это было бы нежелательно по нескольким причинам. Пользователи объектов Piece, у которых они статически типизированы как Pieces, должны будут выполнить приведение, чтобы получить что-то статически типизированное как Player. Кроме того, я должен был бы написать реализацию свойства сам, а не просто использовать @synthesize, или в этом случае фактически @dynamic; Базовые данные генерируют реализации свойств.

Итак, могу ли я дать указание компилятору подавить это предупреждение? Или есть лучший способ написать этот код, который не будет генерировать предупреждение?

Ответы [ 2 ]

0 голосов
/ 18 августа 2010

Является ли владелец отношениями в вашей модели данных? Если это так, вы можете обнаружить, что компилятор запутался, потому что NSManagedObject должен ответить на него.

В противном случае это выглядит как ограничение способа обработки свойств в подклассах или реализации протоколов. Если вы замените NSManagedObject на NSObject в Piece and Player, но проблема все равно возникнет, возможно, стоит сообщить об ошибке в Apple.

В качестве обходного пути, я думаю, вам не следует объявлять свойство в Piece и объявлять отдельный установщик для владельца, т.е.

@interface Piece : NSManagedObject <PieceModel>
{
}
...

//@property (readonly, nonatomic, retain) id<PlayerModel> owner;
// property declaration not needed because it's in the protocol

-(void) setOwner: (Player*) newOwner; 
...

@end

и внедрите установщик вручную.

На несвязанной ноте я бы не стал объявлять свойства неатомарными, если бы у меня не было свидетельства от профилировщика, что это обеспечивает значительное повышение производительности.

0 голосов
/ 18 августа 2010

Это не генерирует предупреждений ...

@protocol PlayerModel <NSObject>
@end

@protocol PieceModel <NSObject>
- (id<PlayerModel>)owner;
@end

@interface Player : NSObject <PlayerModel> {
}
@end

@interface Piece : NSObject <PieceModel> {
}
@property (nonatomic,retain) Player* owner;
@end

Конечно, вы не сможете использовать @synthesize для PieceModel.owner, но это не так уж много дополнительной работы.Помните, что объявления @property в основном являются просто кратким описанием объявления методов установки и получения и определения поведения методов, сгенерированных @ synthesize.

Также имейте в виду, что точечная нотация для доступа к свойствам является просто синтаксическим сахаром, так что еслиВы любите точечную нотацию, вы все равно сможете использовать ее для доступа к «владельцу» переменных, объявленных как id .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...