2015-04-03 53 views
2

我有以下聲明:斯威夫特:清理聲明/元編程

var loginServiceUsed: String? = NSUserDefaults.standardUserDefaults().stringForKey(Constants.loginServiceUsed.rawValue) { 
    didSet { 
     NSUserDefaults.standardUserDefaults().setObject(loginServiceUsed, forKey: Constants.loginServiceUsed.rawValue) 
    } 
} 
var loginServiceToken: String? = NSUserDefaults.standardUserDefaults().stringForKey(Constants.loginServiceToken.rawValue) { 
    didSet { 
     NSUserDefaults.standardUserDefaults().setObject(loginServiceToken, forKey: Constants.loginServiceToken.rawValue) 
    } 
} 
... 

重複半打倍。這種相同的模式讓我有些不安。如果我正在編寫ruby代碼,那麼我會在這裏放一些元編程,它將是一個變量名稱的數組和相關的4-5行代碼 - 我會選擇6行代碼碼。

有清理這些聲明的好方法嗎?

我很樂意以這樣一種方式來重構它,使每個聲明成爲一條線 - 是否有某種方法可以通過閉包來實現?

+0

每個聲明*是*一行。其餘的是'didSet'屬性觀察器方法。 – nhgrif 2015-04-03 01:54:38

+0

你有沒有把這些作爲屬性?看起來像這應該只是一個getDefault/setDefault函數使用你的常量。我會在這種情況下使用枚舉,但要麼擺脫魔術字符串。 – Nick 2015-04-04 00:02:07

+0

我確實喜歡它們作爲屬性。我正在考慮用postfix =運算符編寫一個結構體。我認爲這將是一個優雅的解決方案。 loginServiceUsed:NSUserDefaultsBackedVariable(,key:String)。如何在不調用rawValue之類的情況下返回rawValue ... – kwerle 2015-04-04 19:07:29

回答

0

到目前爲止,該解決方案我是不是幾乎一樣光滑,因爲我想:

struct BackedVariable<type: AnyObject> { 

    var key: String 

    init(_ key: String) { 
     self.key = key 
    } 

    var value: type? { 
     set { 
      NSUserDefaults.standardUserDefaults().setObject(newValue, forKey: key) 
     } 
     get { 
      let returnValue = NSUserDefaults.standardUserDefaults().objectForKey(self.key) as? type 
      return returnValue 
     } 
    } 
} 

var bv: BackedVariable = BackedVariable<NSString>("backed") 
bv.value = "foo" 
println("\(bv.value!)") // "foo" 

所以

var loginServiceUsed: BackedVariable<String>("loginServiceUsed") 
loginServiceUsed.value = "SomeValue" 
doSomethingWith(loginServiceUsed.value) 

這並不可怕,但它不是我所希望的。我不能重寫=運算符來做更自然的賦值。我正在考慮添加一些其他運營商,所以我可以做

loginServiceUser <operator assigns> newValue 

它封裝了重複的複雜性,所以這很好,無論如何。


後來......

我可以添加

postfix operator & { } 
postfix operator &! { } 

func &=<type: AnyObject>(inout oldValue:BackedVariable<type>, newValue: type?) -> BackedVariable<type> { 
    oldValue.value = newValue 
    return oldValue 
} 

postfix func &<type>(object: BackedVariable<type>) -> type? { 
    return object.value 
} 

postfix func &!<type>(object: BackedVariable<type>) -> type { 
    return (object&)! 
} 

然後做

loginServiceUser &= "bar" 
println("\(loginServiceUser.value!)") // "bar" 
println("\((loginServiceUser&)!)") // "bar" 
println("\(loginServiceUser&!)") // "bar" 

這我不認爲是一個巨大的勝利。但它可能會達到最好。