Objective-C协议泛型

10

Objective-C协议可以是泛型的吗?

参照这篇教程,我基本上想要像这样的东西:

@protocol ItemsStore<__covariant ObjectType> <NSObject>

-(NSArray <ObjectType> *)items;

@end

这是一个适用于某些 ObjectType 的通用协议,它“实现”(“继承”)另一个协议NSObject

Translated text:

这是一个适用于某些 ObjectType 的通用协议,它“实现”(“继承”)另一个协议NSObject


1
FYI - https://dev59.com/ZFsW5IYBdhLWcg3wTlu8 - rmaddy
这怎么可能没有出现在我的搜索结果中。谢谢。 - mllm
我认为这没有意义。将一个类标记为泛型协变允许该类的实例符合泛型。但是,如果将其放在协议中,编译器不知道您的意图是什么。 - John Bennedict Lorenzo
4个回答

4

正如@rmaddy所建议的,以及参考这个问题,这是不可能的。 可惜了,那就转到Swift吧...


1
也许你可以在接口中将其重新定义为通用的。
@protocol ItemsStore <NSObject>

- (NSArray *)items;

@end

@interface MyItemsStore<ObjectType> : NSObject <ItemsStore>

- (NSArray <ObjectType> *)items;

@end

尽管如此,这似乎是不太可能的情况。你最好只是定义每个子类中项目的类型,就像苹果在他们的核心数据模型生成中所做的那样,使用NSFetchRequest

只有我需要的语法。永远都不会有太多。尖括号。 - Anton Tropashko

0

可能这个问题和我的源问题完全相同。设计的想法很好,但在ObjC中无法实现。我也对此感到困惑。我认为它可能可以通过某种方式实现:

@protocol Prototype<__covariant OtherProtocolOrClass> <NSObject>
/// Construct an object of the desired class or protocol
@property (nonatomic, nonnull, readonly) <OtherProtocolOrClass> objectFromPrototype;
@end

(我还没有测试过@protocol Prototype <NSObject,__covariant OtherProtocolOrClass>,但我认为它会失败。)

我的框架中的另一个对象(它是一个集合)声明说,如果有返回实例的原型,则可以自动构造一个NSArray<ObjectType>*,如下所示:

@interface ValueProto : NSObject <Prototype<id<Value>>>
@end

@implementation ValueProto
-(id<Value>)objectFromPrototype {
    return [Value new];
}
@end

在我的梦中,这个集合是这样构建的:
MyCollection<id<Value>>* const collection = [MyCollection new];
collection.prototype = [ValuesProto new];

如果您访问集合的属性,那么您的id<Value>对象数组将会动态构建:

-(NSArray<id<Value>>*)values {
    NSArray*const sourceCollection = ...
    NSMutableArray<id<Value>>* const result = [NSMutableArray arrayWithCapacity:sourceCollection.count];
    for (id o in sourceCollection) {
        id<Value> v = self.prototype.objectFromPrototype;
        v.content = o;
        [result addObject:v];
    }
    return result;
}

相反,我的一个类的对象必须是原型本身:

-(id)objectFromPrototype {
    return [self.class new];
}

这与我的所谓的“注入器”相冲突,它通过协议构建和返回对象,而不是类。

如果有任何苹果工程师正在阅读此内容:

请为ObjC提供协议协变。它还没有死!:-)


0
为什么不使用通用抽象类?
@interface AbstractItemStore <__covariant ObjectType> : NSObject

- (NSArray<ObjectType> *)items;

@end

@implementation AbstractItemStore

- (NSArray<id> *)items {
    NSParameterAssert("Not implemented!");
    return nil;
}

@end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接