Objective-C 协议可以是通用的吗?
按照本教程,我基本上是在寻找类似的东西:
@protocol ItemsStore<__covariant ObjectType> <NSObject>
-(NSArray <ObjectType> *)items;
@end
对于某些ObjectType
“实现”(“继承”)另一个协议的人来说,这是一个通用协议NSObject
Objective-C 协议可以是通用的吗?
按照本教程,我基本上是在寻找类似的东西:
@protocol ItemsStore<__covariant ObjectType> <NSObject>
-(NSArray <ObjectType> *)items;
@end
对于某些ObjectType
“实现”(“继承”)另一个协议的人来说,这是一个通用协议NSObject
正如@rmaddy 所建议的那样,并提到这个问题,这是不可能的。耻辱,然后转向斯威夫特......
也许您可以在界面中将其重新定义为泛型。
@protocol ItemsStore <NSObject>
- (NSArray *)items;
@end
@interface MyItemsStore<ObjectType> : NSObject <ItemsStore>
- (NSArray <ObjectType> *)items;
@end
不过,这似乎不太可能发生。您最好只定义每个子类中项目的类型。就像 AppleNSFetchRequest
在其核心数据模型生成中所做的那样。
为什么不使用泛型抽象类?
@interface AbstractItemStore <__covariant ObjectType> : NSObject
- (NSArray<ObjectType> *)items;
@end
@implementation AbstractItemStore
- (NSArray<id> *)items {
NSParameterAssert("Not implemented!");
return nil;
}
@end
可能,这个问题与我的问题完全相同。嗯,设计理念很棒,但不适用于 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>*
我的框架中的另一个对象(它是一个集合)指出,如果有一个返回实例的 Prototype ,它可以自动构造一个对象类型,如下所示:
@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];
}
这与我所谓的“注入器”冲突,后者通过协议而不是类来构造和返回对象。
如果任何 Apple 工程师正在阅读此内容:
请为 ObjC 提供协议协变。它还没有死!:-)