我有一个类,需要使用NSObject子类的变量进行设置,并实现某个协议。
protocol ProtoTest {
var foo: Int { get set }
}
class AClass: NSObject, ProtoTest {
var foo: Int = 3
}
class BClass: NSObject, ProtoTest {
var foo: Int = 4
}
class Consumer {
var protoInstance: ProtoTest? //Does not cary any information of the class just the protocol
var protoInstance2: protocol<NSObjectProtocol, ProtoTest>?
init(x: ProtoTest) {
self.protoInstance = x
self.protoInstance2 = nil
}
init(x: protocol<NSObjectProtocol, ProtoTest>) {
self.protoInstance2 = x
self.protoInstance = nil
}
func doSomething() {
if let x = protoInstance {
x.copy() //'ProtoTest' does not have a member named 'copy'
}
if let x = protoInstance2 {
x.copy() //protocol<NSObjectProtocol, ProtoTest> does not have a member named 'copy'
}
}
}
在上面的例子中,变量的声明都不起作用。既然他们都不知道基类?
如何在swift中实现此功能?
答案 0 :(得分:2)
Swift中通常的等同于NSObject<Protocol>
只是Protocol
。通常,此协议被声明为类协议,以保证它将被类采用。
如果您还需要NSObject协议方法(例如respondsToSelector:
),则make Protocol采用NSObjectProtocol。
如果问题仅仅是您想要调用copy()
并且您无法说服编译器让您这样做,那么也可以采用NSCopying(或者只使用respondsToSelector:
和{ {1}}完全绕过编译器。)
答案 1 :(得分:1)
你可以通过几种方式做到这一点。首先,您可以Consumer
通用:
class Consumer<T: NSObject where T: Prototest> {
var protoInstance: T?
var protoInstance2: T?
}
如果您这样做,那么对protoInstance
或protoInstance2
的所有引用都将从NSObject
继承,您将能够直接在对象上调用.copy()
等方法
如果您不希望Consumer
是通用的,则可以使用通用参数强制限制init
方法,如下所示:
class Consumer {
// ...
init<T: NSObject where T: Prototest>(x: T) {
protoInstance = x
}
}
如果你这样做,我们保证protoInstance
将成为NSObject
,但你必须强制转换为NSObject
才能使用NSObject
中的任何一个方法:
func doSomething() {
if let x = protoInstance as? NSObject {
x.copy()
}
}
编辑:
请注意,我不确定您是否真的希望protoInstance
和protoInstance2
属于不同的类型我对您的问题有点不清楚。如果您确实希望它们是不同的类型,我可以为此答案添加其他建议。