在Swift中通过下标访问单例属性
我有一个单身班:在Swift中通过下标访问单例属性,swift,singleton,subscript,kvc,Swift,Singleton,Subscript,Kvc,我有一个单身班: class Session { static let sharedInstance = Session() private init() {} // app properties var token: String! var promotions: JSON! } 在networking类中,我有多个异步调用,我使用map函数对每个url进行调用: let urls = [ "promotions": "http:..." ] let results =
class Session {
static let sharedInstance = Session()
private init() {}
// app properties
var token: String!
var promotions: JSON!
}
在networking类中,我有多个异步调用,我使用map
函数对每个url进行调用:
let urls = [ "promotions": "http:..." ]
let results = urls.map { (k, url) in
self.getFromApi(url, params: ["token" : token]) { response in
guard response as? JSON != nil else { return }
Session.sharedInstance[k] = response
// the above should compile to Session.sharedInstance["promotions"] = response.
}
问题在于试图通过下标设置sharedInstance上的响应。我尝试在Singleton上实现一个下标,但没有成功:
subscript(property: Any) -> Any {
get {
return Session.sharedInstance[property]
}
set(newValue) {
Session.sharedInstance[property] = newValue
}
}
我还尝试通过遵守NSObject
和使用KVC
放弃订阅,但是这也不起作用&而且我失去了所有类型安全性
非常感谢您的任何帮助或建议。
提前谢谢。你可以让你的单身汉成为一个包类。您有一个保存JSON或属性的字典。其他一切都只是计算值
class Session {
static let sharedInstance = Session()
private init() {}
// app properties
var token: String!
private var fetchedJSON : [String:Any] = [:]
var keys : [String] {
return Array(fetchedJSON.keys)
}
// handy to do downcasts in here
var promotions : JSON? {
get {
if let promotions = fetchedJSON["promotions"] as? JSON {
return promotions
} else {
return nil
}
}
set(value) {
fetchedJSON["prmotions"] = value
}
}
subscript(property: String) -> Any? {
get {
return fetchedJSON[property]
}
set(newValue) {
fetchedJSON[property] = newValue
}
}
}
或者创建一个有限的KVC(这也可以通过Oliver Borchert在另一个答案中所述的反射来实现):
你可以利用反射。我不经常使用它,所以如果你有任何进一步的问题,只需谷歌“快速反应”。但要小心:反射可能看起来不错,但速度很慢,并且只适用于
NSObject
子类(我想,但可以尝试一下)。其工作原理如下:
subscript(property: String) -> Any {
get {
for i in 0..<reflect(self).count { // loop through all properties
if reflect(self)[i].0 == property { // find property with specified name
return reflect(self)[i].1.summary // return property's value
}
}
fatalError("no such property found")
} set(newValue) {
for i in 0..<reflect(self).count { // loop through all properties
if reflect(self)[i].0 == property { // find property with specified name
self.setValue(newValue, forKey: property) // not possible to do otherwise in Swift
return
}
}
}
}
下标(属性:字符串)->任意{
得到{
对于0中的i..为什么需要下标?我猜是因为您有更多的属性,如促销
?也不需要执行:会话。sharedInstance[property]=newValue
只需使用:self.[property]=newValue
然后,很明显您正在创建一个递归下标。这很好。谢谢@r-menke!@KyleGillen哪一个很棒?我选择了类似KVC的选项。考虑到我有很多属性,它看起来不那么麻烦。
subscript(property: String) -> Any {
get {
for i in 0..<reflect(self).count { // loop through all properties
if reflect(self)[i].0 == property { // find property with specified name
return reflect(self)[i].1.summary // return property's value
}
}
fatalError("no such property found")
} set(newValue) {
for i in 0..<reflect(self).count { // loop through all properties
if reflect(self)[i].0 == property { // find property with specified name
self.setValue(newValue, forKey: property) // not possible to do otherwise in Swift
return
}
}
}
}