【发布时间】:2021-05-05 18:27:06
【问题描述】:
TL:DR
我怎样才能进行编译,以便协议可以应用于任何 BaseObject 的具体实现,特别是,以便它可以访问someFuncUnrelatedToTypeConstraint(这才是真正的目标) ?
@interface BaseObject <__covariant TypeConstraint> : NSObject
- (TestObject*)someFuncUnrelatedToTypeConstraint;
@end
protocol ProtocolOnlyApplicableToBaseObject : BaseObject {}
注意:这不会编译,因为它抱怨我需要为 BaseObject 指定类型参数,但仅此而已......我希望这适用于任何/所有 BaseObject<T> 类型,无论 @987654326 是什么@是。
现在是完整的代码...
在我们的 ObjC 代码库中,我们有一个具体的对象和一个像这样定义的泛型(示例过于简单)。这表示只有 NSObject 或其子类之一可以满足类型要求。
@interface TestObject : NSObject
@end
@interface BaseObject <__covariant TypeConstraint> : NSObject
- (TestObject*)someFuncUnrelatedToTypeConstraint;
@end
我们也有这些(同样,过于简单化的)ObjC 子类,最后一个省略了类型,所以它默认为 NSObject 隐式。
@interface ConcreteObjectA : BaseObject<UIView>
@end
@interface ConcreteObjectB : BaseObject<UIWindow>
@end
@interface ConcreteObjectC : BaseObject
@end
现在我们正在尝试编写一个 Swift 协议和一个只能应用于 BaseObject 实例的配对扩展,因为扩展需要调用函数 someFuncUnrelatedToTypeConstraint()。
protocol ProtocolForBaseObject : BaseObject {
associatedtype ReturnType:SomeTypeAcceptingTestObject
}
extension ProtocolForBaseObject {
func someTest() -> ReturnType {
let testObject = self.someFuncUnrelatedToTypeConstraint()
return ReturnType(testObject)
}
}
目标是我们可以在 Swift 中调用它...
extension ConcreteObjectA : ProtocolForBaseObject {
typealias ReturnType = ReturnTypeA
}
let objA = ConcreteObjectA()
let returnTypeA = objA.someTest()
extension ConcreteObjectB : ProtocolForBaseObject {
typealias ReturnType = ReturnTypeB
}
let objB = ConcreteObjectB()
let returnTypeB = objB.someTest()
extension ConcreteObjectC : ProtocolForBaseObject {
typealias ReturnType = ReturnTypeC
}
let objC = ConcreteObjectC()
let returnTypeC = objC.someTest()
问题是 ProtocolForBaseObject 无法编译,因为它说我必须指定泛型类型约束...
Reference to generic type 'BaseObject' requires arguments in <...>
但问题是我不在乎泛型的类型约束是什么。我希望这适用于泛型的 所有 实例,因为我试图访问的函数无论如何都不使用该类型,因此协议没有理由关心该类型是什么。
为了解决这个问题,我尝试添加NSObject 作为类型约束,但这似乎也不起作用,因为BaseObject<NSObject> != BaseObject<UIView> 即使UIView 是NSObject 的子类。
protocol ProtocolForBaseObject : BaseObject<NSObject> {}
那么,无论类型约束如何,如何构建协议以应用于BaseObject 泛型的所有具体实例?
【问题讨论】:
-
嗯有点困惑。为什么不直接将协议应用于 BaseObject 而不是继承 BaseObject 类型的协议,以便稍后再次应用于其自身。 BaseObject 已经继承自 NSObject,所以 BaseObject
没有意义。 -
问题是我只希望该协议对
BaseObject类型的对象可用/适用,因为该协议的扩展需要访问 inBaseObject(特别是someFuncUnrelatedToTypeConstraint方法),所以如果我不将协议限制为BaseObject,它甚至无法访问someFuncUnrelatedToTypeConstraint。有道理?也就是说,如果你能找到解决我刚刚概述的问题的方法,我全力以赴! -
另外,我想你可能误解了我的意思。
BaseObject<NSObject>与BaseObject本身 是NSObject无关。这说明泛型的 类型约束 是NSObject但同样,这只是试图解决编译器抱怨我必须给它一些类型的问题,即使我没有关心那是什么类型。这就是问题所在。 -
我说得对吗,您需要将
BaseObject设为抽象类吗?
标签: swift objective-c generics subclass