我在这里了解为什么我实施的解决方案不起作用。基本上,我有一个名为MyClass
的类,并且在该类中,我希望有一个从plist文件创建的静态字典。像这样:
class MyClass {
static var myDic: [String: String] = NSDictionary(contentsOfFile: Bundle(for: self).path(forResource: "filename", ofType: "plist")!) as! [String: String]
}
如果这样做,编译器会抱怨:
Cannot convert value of type '(MyClass) -> () -> (MyClass)' to expected argument type 'AnyClass' (aka 'AnyObject.Type')
但是如果我更改myDic
var并创建一个返回该dic的静态方法,那一切都很好:
class MyClass {
static func myDic() -> [String: String] {
return NSDictionary(contentsOfFile: Bundle(for: self).path(forResource: "PlayerRolesWithColors", ofType: "plist")!) as! [String: String]
}
}
这里有两个问题:
'(MyClass) -> () -> (MyClass)'
谢谢。
答案 0 :(得分:1)
你可以
class MyClass {
static var myDic: [String: String] = NSDictionary(contentsOfFile: Bundle(for:MyClass.self).path(forResource: "filename", ofType: "plist")!) as! [String: String]
}
由于您无法在静态变量内访问self
或使用包标识符
class MyClass {
static var myDic: [String: String] = NSDictionary(contentsOfFile: Bundle(identifier: "comThisBundle")!.path(forResource: "filename", ofType: "plist")!) as! [String: String]
}
答案 1 :(得分:1)
您可以简单地使用类名代替self
。
您也不应该使用NSDictionary
然后转换为Swift Dictionary
。请改用PropertyListDecoder
。
class MyClass {
static let myDic = try! PropertyListDecoder().decode([String:String].self, from: try! Data(contentsOf: Bundle(for: MyClass.self).url(forResource: "filename", withExtension: "plist")))
}
答案 2 :(得分:1)
让我们看一个更简单(有效)的示例,让您的核心问题保持不变:
class ClassName {
static var bundle = Bundle(for: ClassName.self)
static func getBundle() -> Bundle {
return Bundle(for: self)
}
}
首先,请注意Bundle(for: AnyClass)
采用的是对象类型。
顶级变量将self
作为实例类型ClassName
访问,而不管它是否声明为let
/ var
/ lazy
/计算的还是静态的。
所以:
static var bundle = Bundle(for: self)
与:
static var bundle = Bundle(for: ClassName())
两者均无效,并产生以下错误:
无法将类型“ ClassName”的值转换为预期的参数类型“ AnyClass”(又名“ AnyObject.Type”)
可以肯定的是,这是因为我们传递的是实例类型,而不是预期的Object类型。
static var bundle = Bundle(for: ClassName.self)
对于静态函数,这有点不同。
调用静态方法的元类型在您的方法中可以作为
self
使用(简单地作为隐式参数传递)。
在我的示例中,我们有:
static func getBundle() -> Bundle {
return Bundle(for: self)
}
调用ClassName.getBundle()
时,ClassName.Type
被隐式传递给该函数。
现在,在静态函数中,self
的类型为ClassName.Type
,它是一种对象类型,可以直接在Bundle(for:)
或接受对象类型作为参数的类似函数中应用。>
因此,静态函数以self
的身份访问ClassName.Type
,这与ClassName.self
相同,只是因为隐式传递而看不见。
您可以在self
函数中确认static
的这种行为,并在以下示例中甚至观察self
在正常函数中的行为:
class ClassName {
static func check() {
print("static function check")
print(type(of: self)) //ClassName.Type
//same as
print(type(of: ClassName.self)) //ClassName.Type
//test
print(type(of: self) == type(of: ClassName.self)) //true
}
func check() {
print("normal function check")
print(type(of: self)) //ClassName
//test
print(type(of: self) == type(of: ClassName.self)) //false
}
}
ClassName.check()
ClassName().check()
还向我们展示了普通函数将self
作为ClassName
的实例类型来访问Bundle(for:)
,
self
采用对象类型ClassName
的身份访问self
,这是实例类型ClassName
的身份访问self
,这是实例类型ClassName.Type
的身份访问http://cre.cit.api.here.com/2/calculateroute.json?app_id=xxxx&app_code=xxxx&mode=fastest;truck;traffic:disabled&driver_cost=10&waypoint0=55.308989,10.805059&waypoint1=55.368920,11.288338&attributes=ROAD_GEOM_FCn(BRIDGE)
,这是一种对象类型,因为它隐式传递给了函数