Objective c协议泛型

时间:2016-02-03 17:10:54

标签: objective-c generics objective-c-protocol

Objective-C协议可以通用吗?

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

@protocol ItemsStore<__covariant ObjectType> <NSObject>

-(NSArray <ObjectType> *)items;

@end

某些ObjectType的通用协议&#34;实现&#34; (&#34;继承&#34;)另一个协议NSObject

4 个答案:

答案 0 :(得分:4)

正如@rmaddy建议的那样,并且如this questions所述,这是不可能的。 惭愧,然后转移到斯威夫特......

答案 1 :(得分:0)

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

@protocol ItemsStore <NSObject>

- (NSArray *)items;

@end

@interface MyItemsStore<ObjectType> : NSObject <ItemsStore>

- (NSArray <ObjectType> *)items;

@end

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

答案 2 :(得分: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

我梦s以求,收藏的结构是这样的:

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

与我所谓的“注入器”(Injector)冲突,后者通过协议而非类来构造和返回对象。

如果有任何Apple工程师正在阅读以下内容:

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

答案 3 :(得分:0)

为什么不使用泛型抽象类?

@interface AbstractItemStore <__covariant ObjectType> : NSObject

- (NSArray<ObjectType> *)items;

@end

@implementation AbstractItemStore

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

@end