Objective c 协议泛型

Objective c protocol generics

Objective-C 协议可以通用吗?

关注 this tutorial,我基本上是在寻找类似的东西:

@protocol ItemsStore<__covariant ObjectType> <NSObject>

-(NSArray <ObjectType> *)items;

@end

这是一些 ObjectType 的通用协议 "implements" ("inherits") 另一个协议 NSObject

正如@rmaddy 所建议的那样,并提到 this questions,这是不可能的。 耻辱,移动到 Swift 然后...

也许您可以在界面中将其重新定义为通用。

@protocol ItemsStore <NSObject>

- (NSArray *)items;

@end

@interface MyItemsStore<ObjectType> : NSObject <ItemsStore>

- (NSArray <ObjectType> *)items;

@end

虽然这似乎不太可能发生。您最好只定义每个子类中的项目类型。就像 Apple 在其核心数据模型生成中对 NSFetchRequest 所做的那样。

大概,这个问题和我的出处问题一模一样。好吧,设计的想法很棒,但不适用于 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>*,如果有一个 returns 实例的原型,如下所示:

@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;
}

我的 class' 对象之一必须是原型本身:

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

这与我所谓的 'Injector' 冲突,后者通过协议而不是 classes 构造和 returns 对象。

如果有 Apple 工程师正在阅读本文:

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

为什么不使用通用摘要 class?

@interface AbstractItemStore <__covariant ObjectType> : NSObject

- (NSArray<ObjectType> *)items;

@end

@implementation AbstractItemStore

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

@end