删除包含子类的子类属性的 Xcode "incompatible type" 类型警告
Remove Xcode "incompatible type" type warning for subclassed properties containing subclasses
Class A 将 属性 "items" 定义为包含 class X.
实例的有序集
Class B subclasses A,并将 "items" 属性 重新定义为包含 class Y 实例的有序集,子class 的 X.
// Defined in class A
@property NSOrderedSet<__kindof X *> *items;
// Defined in class B
@property NSOrderedSet<__kindof Y *> *items;
所有 Y 都是 X 的一种,因此子 classed 属性 应该有效,但是 Xcode 在 class B 中生成以下警告:
Property type 'NSOrderedSet<__kindof Y *> *' is incompatible with type 'NSOrderedSet<__kindof X *> *' inherited from 'A'
我真的做错了什么还是 Xcode 错误?我怎样才能删除这个警告?
你不能说这是一个错误,因为它是一个讨论的主题,在一个 subclass 中这样的参数 subclassing 是正确的还是错误的。应用 Liskov's substitution principle 必须可以将 X
的项目添加到集合中,因为基础 class 允许 this.Then 这是违反原则的,如果 sub class禁止。
但是,您应该记住 "typing" 集合是在 Swift 中引入的,目的是为 Swift 编译器提供更多类型信息。喜欢。
纯粹是反概念Objective-C。如果您不想使用 Swift.
中的 class,只需省略它
给大家举个更简单的例子。拥有:
@interface BaseValue : NSObject
…
@end
@interface Subvalue : BasValue
- (void)anotherMethod;
…
@end
@interface BaseHolder : NSObject
@property NSMutableSet<BaseValue*>* values;
@end
@interface Subholder : BaseHolder
@property NSMutableSet<Subvalue*>* values;
@end
在此示例中,集合的成员被限制为 Subvalue
的实例。因此 Subholder
内的代码——以及任何明确处理 Subholder
实例的代码都可以预期,集合内的项目可以使用选择器 anotherMethod
接收消息。
但是如果你这样做
BaseValue *baseValue = [BaseValue new];
BaseHolder *baseHolder = [Subholder new]; // Get an instance of *Subholder*. The assignment is allowed by Liskov … As long as Subholder introduces no additional constraints.
[baseHolder.values addObject:baseValue]; // From the compiler's point of view legal, because you said nothing about a subclass
这会中断,因为在运行时它是 Subholder
的一个实例,但它的集合中有一个与约束不匹配的成员。
Class A 将 属性 "items" 定义为包含 class X.
实例的有序集Class B subclasses A,并将 "items" 属性 重新定义为包含 class Y 实例的有序集,子class 的 X.
// Defined in class A
@property NSOrderedSet<__kindof X *> *items;
// Defined in class B
@property NSOrderedSet<__kindof Y *> *items;
所有 Y 都是 X 的一种,因此子 classed 属性 应该有效,但是 Xcode 在 class B 中生成以下警告:
Property type 'NSOrderedSet<__kindof Y *> *' is incompatible with type 'NSOrderedSet<__kindof X *> *' inherited from 'A'
我真的做错了什么还是 Xcode 错误?我怎样才能删除这个警告?
你不能说这是一个错误,因为它是一个讨论的主题,在一个 subclass 中这样的参数 subclassing 是正确的还是错误的。应用 Liskov's substitution principle 必须可以将 X
的项目添加到集合中,因为基础 class 允许 this.Then 这是违反原则的,如果 sub class禁止。
但是,您应该记住 "typing" 集合是在 Swift 中引入的,目的是为 Swift 编译器提供更多类型信息。喜欢。
纯粹是反概念Objective-C。如果您不想使用 Swift.
中的 class,只需省略它给大家举个更简单的例子。拥有:
@interface BaseValue : NSObject
…
@end
@interface Subvalue : BasValue
- (void)anotherMethod;
…
@end
@interface BaseHolder : NSObject
@property NSMutableSet<BaseValue*>* values;
@end
@interface Subholder : BaseHolder
@property NSMutableSet<Subvalue*>* values;
@end
在此示例中,集合的成员被限制为 Subvalue
的实例。因此 Subholder
内的代码——以及任何明确处理 Subholder
实例的代码都可以预期,集合内的项目可以使用选择器 anotherMethod
接收消息。
但是如果你这样做
BaseValue *baseValue = [BaseValue new];
BaseHolder *baseHolder = [Subholder new]; // Get an instance of *Subholder*. The assignment is allowed by Liskov … As long as Subholder introduces no additional constraints.
[baseHolder.values addObject:baseValue]; // From the compiler's point of view legal, because you said nothing about a subclass
这会中断,因为在运行时它是 Subholder
的一个实例,但它的集合中有一个与约束不匹配的成员。