1

我收到这个警告。我想做的是有一个类族和一个并行的协议族。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 类的每个实例都为 owner 属性返回一个 Player 实例,它符合 PlayerModel 协议。我明白为什么会有这样的警告。尝试将任何符合 PlayerModel 的对象分配给所有者并不是那么安全,因为它可能不属于 Player 类,但在这种情况下这不是问题,因为该属性被声明为协议的只读。

请注意,我还将该属性声明为保留,如果我没记错的话,这对于只读属性是没有意义的,但是如果我不这样做,我也会收到关于协议和类之间不匹配的不同警告。至少编译器不会抱怨一个属性是只读的而另一个不是。

我知道我可以将类属性声明为返回id <PlayerModel>,但出于几个原因,这是不可取的。将 Piece 对象静态类型为 Pieces 的用户必须进行强制转换才能获得静态类型为 Player 的东西。另外,我必须自己编写属性实现,而不仅仅是使用@synthesize,或者在这种情况下实际上是@dynamic;Core Data 生成属性实现。

那么,我可以指示编译器禁止此警告吗?还是有更好的方法来编写不会生成警告的代码?

4

2 回答 2

0

所有者是您的数据模型中的关系吗?如果是这样,您可能会发现编译器感到困惑,因为 NSManagedObject 需要响应它。

否则,它看起来像是在子类或协议实现中处理属性的方式的限制。如果您在 Piece and Player 中将 NSManagedObject 替换为 NSObject 并且仍然遇到问题,则可能值得向 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

并手动实现setter。

在不相关的说明中,我不会费心将属性声明为非原子的,除非我有来自分析器的证据表明它提供了显着的性能提升。

于 2010-08-18T13:00:47.983 回答
0

这不会产生任何警告......

@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 声明基本上只是声明 setter 和 getter 以及定义 @synthesize 生成的方法的行为的简写。

还要记住,用于访问属性的点表示法只是语法糖,所以如果您喜欢点表示法,您仍然可以使用它来访问声明为 id<PieceModel> 的变量的“所有者”。

于 2010-08-18T05:30:39.187 回答