这里的问题是它Self可能比Login. 假设您创建了一个子类Login:
class TopSecretLogin : Login {
var topSecret : String?
}
TopSecretLogin现在,当您在(假设首先Login符合)的实例上使用您的协议扩展时JSONResource- 您的processJSON方法说它返回Self,TopSecretLogin在这种情况下就是这样。但是,您正在尝试返回一个Login. 因此编译器不高兴,因为您不能将超类传递给期望其子类的东西。
解决方案取决于您是否打算Login被子类化。如果您不打算将其子类化,则只需将方法签名更改为返回 a Login,然后制作Logina final class。
如果您确实打算这样做,则需要将所需的初始化程序添加到,允许您在协议扩展中Login构造任意实例。Self示例设置可能如下所示:
protocol JSONResource {}
class Login : NSObject, JSONResource {
var username: String?
var firstName: String?
required override init() {
super.init()
}
}
class TopSecretLogin : Login {
var topSecret : String?
required init() {
super.init()
}
}
extension JSONResource where Self : Login {
func processJSON(data: NSData) -> Self {
// do some processing...
return Self()
}
}
let someData = // ...
let l = Login()
l.processJSON(someData) // returns Login
let t = TopSecretLogin()
t.processJSON(someData) // returns TopSecretLogin
processJSON虽然说了这么多,但如果是静态方法而不是实例方法不是更有意义吗?对我来说,它看起来不需要对实例进行操作,它只是从给定的一组NSData.
您可能还想考虑制定processJSON协议要求,就像任何JSONResource应该能够做到的那样processJSON?在这种情况下,您需要扩展Login而不是协议本身来实现该方法。self.init()然后,您可以在静态范围或self.dynamicType.init()实例范围内创建新实例。
您可能还需要考虑使用初始化程序执行此操作:
protocol JSONResource {
init(jsonData:NSData)
}
class Login : NSObject, JSONResource {
var username: String?
var firstName: String?
required init(jsonData:NSData) {
// do some processing
super.init()
}
}
class TopSecretLogin : Login {
var topSecret : String?
required init(jsonData:NSData) {
// do some processing
super.init(jsonData:jsonData)
}
}
let someData = // ...
let l = Login(jsonData: someData) // returns Login
let t = TopSecretLogin(jsonData: someData) // returns TopSecretLogin