我在swift中有一个问题,我想在类func中检查协议一致性,然后在检查成功时使用一些静态属性。这是游乐场代码:
import UIKit
@objc protocol SearchableObject {
static var sortDescriptors: [NSSortDescriptor] { get }
}
class Test: NSObject {
}
extension Test {
class func loadData() {
if self is SearchableObject {
println(valueForKey("sortDescriptors"))
}
else {
println("not searchable")
}
}
}
class SearchableTest: Test, SearchableObject {
class var sortDescriptors: [NSSortDescriptor] {
return [NSSortDescriptor(key: "property", ascending: true)]
}
}
Test.loadData() // prints "not searchable"
SearchableTest.loadData() // prints "Optional((\n "(property, ascending, compare:)"\n))"
问题是我可以检查协议一致性,但我不能自我,这就是我使用valueForKey()的原因。
(self as SearchableObject).sortDescriptors
^ 'SearchableObject' does not have a member named 'sortDescriptors'
将self转换为符合SearchableObject的实例,使静态var无法访问。由于不喜欢valueForKey()方法,我想问一下是否有更好的方法来实现这个目标?
提前致谢:)
答案 0 :(得分:4)
在类方法中,self
是一个类,而不是实例。所以正确但非工作的方式是:
class func loadData() {
if let cls = self as? SearchableObject.Type {
// ^^^^^
println(cls.sortDescriptors)
// ^ [!] error: accessing members of protocol type value 'SearchableObject.Type' is unimplemented
}
如你所见,未实现 :(
不用担心,有一种解决方法。只要协议声明为@objc
,AnyClass
就具有该属性。您可以将self
投射到AnyClass
,然后拨打.sortDescriptors
:
class func loadData() {
if self is SearchableObject.Type {
println((self as AnyClass).sortDescriptors)
}
基本上,此解决方法与valueForKey
相同,但它至少不使用字符串。
答案 1 :(得分:2)
self as SearchableObject
会返回SearchableObject
个实例。但是你想要上课。那是SearchableObject.Type
。
所以你的意思是:
extension Test {
class func loadData() {
if let s = self as? SearchableObject.Type { // <<===
println(s.sortDescriptors)
}
else {
println("not searchable")
}
}
}
但是&#34;访问协议类型值的成员......是未实现的。&#34;所以编译器知道这一点,特别是目前无法处理它。当然,如果您使用实例,所有这些都很好:
import Foundation
protocol SearchableObject {
var sortDescriptors: [NSSortDescriptor] { get }
}
class Test {}
extension Test {
func loadData() {
if let s = self as? SearchableObject {
println(s.sortDescriptors)
}
else {
println("not searchable")
}
}
}
class SearchableTest: Test, SearchableObject {
static var sharedSortDescriptors = [NSSortDescriptor(key: "property", ascending: true)]
var sortDescriptors: [NSSortDescriptor] { return self.dynamicType.sharedSortDescriptors }
}
Test().loadData() // prints "not searchable"
SearchableTest().loadData()