我具有此属性:
@property (nonatomic) NSMutableArray <__kindof superclass*> *items;
我用一个子类的对象填充它(由于__kindof应该没问题)。我这样检索数组:
NSMutableArray <__kindof subclass*> *items = holderObject.items;
但是现在我收到此编译器警告:
Incompatible pointer types initializing 'NSMutableArray<subclass *> *' with an expression of type 'NSMutableArray<__kindof superclass *> * _Nullable'
这不是__kindof应该为我们做的吗?我在这里做什么错了?
更新2:这仅适用于可变数组。
更新:这是一些显示警告的简单代码:
创建一个新类GenericsError.h:
@import UIKit;
@interface GenericsError : NSObject
@property (nonatomic) NSMutableArray <__kindof UIViewController*> *generics;
@end
在任何viewController中只需添加:
GenericsError *error = [GenericsError new];
NSMutableArray <ViewController*>* controllers = error.generics;
(用ViewController代替您所调用的viewController)。我没有添加或创建任何东西,只是得到了针对Generics-Error的编译器警告。
答案 0 :(得分:0)
NSMutableArray
的通用参数是不变的(它被声明为@interface NSMutableArray<ObjectType>
而不是@interface NSMutableArray<__covariant ObjectType>
或@interface NSMutableArray<__contravariant ObjectType>
)。这意味着类型参数必须完全匹配才能兼容。
这意味着NSMutableArray<NSString *> *
不能分配给NSMutableArray<NSObject *> *
,反之亦然,即使可以将NSString *
分配给NSObject *
。 (另一方面,NSArray
的类型参数是协变的(它声明为NSArray<__covariant ObjectType>
),这意味着NSArray<NSString *> *
可以分配给{{1} }。
NSArray<NSObject *> *
甚至无法分配给NSMutableArray<NSString *> *
,反之亦然,即使NSMutableArray<id> *
可以分配给NSString *
并且id
可以分配给{ {1}},双向。我想这是因为id
关闭了静态类型检查,但仅在使用实际类型NSString *
时才关闭,而对于以id
作为类型参数的类型则不这样做。
id
是id
的“有限”版本-它关闭了静态类型检查,但仅当分配给__kindof superclass *
的子类型或从id
的子类型中分配时才关闭。出于同样的原因,无法将superclass *
分配给以上NSMutableArray<id> *
,也不能将NSMutableArray<someclass *> *
分配给NSMutableArray<__kindof superclass *> *
。
答案 1 :(得分:-1)
您具有继承 A-> B (其中 A 是子类,而 B 是超类),则声明了一个容器保留 A 的实例,但是您试图将 B 的实例放入容器中。不能保证 B 的所有实例也都是 A 的实例。
想象一下还有另一个类 C-> B (其中 C 是 B 和 B 与上述相同的超类)。在这种情况下, C 是 __ kindof B ,但不是 __ kindof A ,因此警告。
长话短说:声明容器时,您需要使用 __ kindof超类,以禁止显示警告。