Objective-C协议可以是泛型的吗?
参照这篇教程,我基本上想要像这样的东西:
@protocol ItemsStore<__covariant ObjectType> <NSObject>
-(NSArray <ObjectType> *)items;
@end
这是一个适用于某些 ObjectType
的通用协议,它“实现”(“继承”)另一个协议NSObject
这是一个适用于某些 ObjectType
的通用协议,它“实现”(“继承”)另一个协议NSObject
Objective-C协议可以是泛型的吗?
参照这篇教程,我基本上想要像这样的东西:
@protocol ItemsStore<__covariant ObjectType> <NSObject>
-(NSArray <ObjectType> *)items;
@end
这是一个适用于某些 ObjectType
的通用协议,它“实现”(“继承”)另一个协议NSObject
这是一个适用于某些 ObjectType
的通用协议,它“实现”(“继承”)另一个协议NSObject
@protocol ItemsStore <NSObject>
- (NSArray *)items;
@end
@interface MyItemsStore<ObjectType> : NSObject <ItemsStore>
- (NSArray <ObjectType> *)items;
@end
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>*
,如下所示:
@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提供协议协变。它还没有死!:-)
@interface AbstractItemStore <__covariant ObjectType> : NSObject
- (NSArray<ObjectType> *)items;
@end
@implementation AbstractItemStore
- (NSArray<id> *)items {
NSParameterAssert("Not implemented!");
return nil;
}
@end