gpt4 book ai didi

objective-c - 我可以在 Objective-C 中将 __kindof 与协议(protocol)一起使用吗?

转载 作者:搜寻专家 更新时间:2023-10-30 20:05:02 27 4
gpt4 key购买 nike

我知道我可以使用 __kindof 来使用 Objective-C 的轻量级泛型。关键字,例如

NSArray<__kindof BaseClass*> *myArray;

这将删除任何将数组中的任何对象分配给派生类的警告。

但是,而不是 BaseClass , 我有 BaseProtocol ,例如我所有的类(class)都符合 BaseProtocol ,不管他们的基类。我想使用轻量级泛型来指示“我的数组由符合 BaseProtocol 的元素组成,但它们可以是任何类”。

例如在 C# 中,我可以说:List<IMyInterface>这意味着该列表由实现 IMyInterface 的元素组成接口(interface)(我知道 C# 具有强大的泛型,而 Objective-C 只有不会阻止编译的轻量级泛型,但你明白了)。

有没有办法在 Objective-C 上实现这个功能?

例如我要写

NSArray<__kindof id<MyProtocol>> //compiles, but as the generic argument is "id", it accepts any object, including invalid ones

NSArray<id<__kindof MyProtocol>> //doesn't compile

这可能吗?

更新:

这是一个完整的独立代码:

@protocol MyProtocol

@end

@interface MyClass : NSObject<MyProtocol>

@end

@implementation MyClass

@end

@interface AnotherClass : NSObject

@end

@implementation AnotherClass

@end



NSMutableArray<__kindof id<MyProtocol>> *myArray;

void test(){
MyClass *myClassInstance = [[MyClass alloc] init];
AnotherClass *anotherClassInstance = [[AnotherClass alloc] init];

myArray = @[].mutableCopy;
[myArray addObject:myClassInstance];
[myArray addObject:anotherClassInstance]; //i get warning. good.

MyClass *returnedInstance = myArray[0];
AnotherClass *anotherInstance = myArray[1]; //why don't I get a warning here?
}

最佳答案

这个语法是正确的:

NSArray <__kindof id <MyProtocol>> *array = ...

您也可以省略 __kindof,仍然享受轻量级泛型。即使没有该关键字,它仍然会警告您添加错误类型的对象。 __kindof 用于从该数组中提取对象并将其分配给子类型而不进行强制转换,否则不需要 __kindof:

NSArray <id <MyProtocol>> *array = ...

如果您将特定类型的对象添加到数组,但该类型不符合 MyProtocol,这两种模式都会向您发出警告。

如果您尝试单独添加类型为 id 的对象,这不会警告您。因此,避免在您的代码中使用不合格的 id 类型,您将享受轻量级泛型。

如果您仍然没有看到警告,请确保您已打开 -Wobjc-literal-conversion 警告。因此,返回第一个项目的build设置并搜索“literal”,您将看到该设置(称为“隐式 Objective-C 文字转换”)。


考虑这个例子:

@protocol MyProtocol
@end

@interface Foo: NSObject <MyProtocol>
@end

@interface Bar: Foo
@end

@interface Baz: NSObject
@end

然后考虑:

Foo *foo = [[Foo alloc] init];
Bar *bar = [[Bar alloc] init];
Baz *baz = [[Baz alloc] init];
id qux = [[Baz alloc] init];

NSArray <id <MyProtocol>> *array1;
array1 = @[foo, bar, baz, qux]; // warning: object of type 'Baz *' is not compatible with array element type 'Foo *'

请注意,这会警告我们关于 baz,而不是 qux。所以要小心使用 id 类型。

id <MyProtocol> object1 = array1[0];      // no warning, great

所以,这是将协议(protocol)用作轻量级通用协议(protocol),并且它按预期工作。

你添加 __kindof 的唯一原因是你想避免这个警告:

Foo *foo1 = array1[0];                    // warning: initializing 'Foo *__strong' with an expression of incompatible type 'id<MyProtocol> _Nullable'

在这种情况下,您将使用 __kindof:

NSArray <__kindof id <MyProtocol>> *array2;
array2 = @[foo, bar, baz]; // again, warning: object of type 'Baz *' is not compatible with array element type 'Foo *'

id <MyProtocol> object2 = array2[0]; // no warning, great

Foo *foo2 = array2[0]; // no warning, great

关于objective-c - 我可以在 Objective-C 中将 __kindof 与协议(protocol)一起使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49199853/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com