2014-10-05 113 views
3

我試圖讓swift中的變量成爲關鍵的應用程序範圍用戶設置,因此每次更改後都必須將其保存到磁盤。有一小部分這些變量,我滿足於應用程序啓動後第一次從磁盤讀取數據。Swift getter代碼重複

我有一些代碼類似於此:

var _myEnumMember:MyEnum? 
var myEnumMember:MyEnum { 
    get { 
     if let value = _myEnumMember { // in memory 
      return value 
     } 
     var c:Cache = Cache() 
     var storedValue:MyEnum? = c.get("SomeStorageKey"); 
     if let value = storedValue { // exists on disk 
      self.myEnumMember = value // call setter to persist 
      return self.myEnumMember // call getter again with value set 
     } 
     self.myEnumMember = .DefaultValue // assign via setter 
     return self.rankingDuration // call getter after `set` 
    } 
    set (newValue){ 
     self._myEnumMember = newValue // assign to memory 
     var c:Cache = Cache() 
     c.put("SomeStorageKey", data: ser) // store in disk 
    } 

我有大約5-6屬性需要做到這一點 - 我不想一遍遍重複自己 - 有什麼辦法幹這個代碼,所以我不必在幾個地方重複這個邏輯?

(注:定價這裏,而不是CR.SE因爲我想答案解釋怎麼幹getter/setter方法在這些情況下,而不是在一個特定的代碼塊收到批判)

+0

我承認,我不知道斯威夫特。但是,看起來好像只有'SomeStorageKey'會在你所有的鍵之間變化。有沒有辦法重構這個?即你的'get'可以把關鍵作爲參數,你的'set'也可以。 – 2014-10-05 11:38:17

回答

5

我工作最近類似的事情 - 這可能是你最好的選擇。我用它作爲嵌套的struct,但它並不嚴格需要嵌套。

首先,定義一個LocalCache型,將處理您的性能的持久性:

struct LocalCache { 
    // set up keys as constants 
    // these could live in your class instead 
    static let EnumKey  = "EnumKey" 
    static let IntKey  = "IntKey" 
    static let StringKey = "StringKey" 

    // use a single cache variable, hopefully? 
    var cache = Cache() 

    // in-memory values go in a Dictionary 
    var localValues: [String: Any] = [:] 

    // fetch from local storage or from disk 
    // note that the default value also sets the return type 
    mutating func fetch<T>(key: String, defaultValue: T) -> T { 
     if localValues[key] == nil { 
      localValues[key] = cache.get(key) ?? defaultValue 
     } 
     return localValues[key]! as T 
    } 

    // save in both local storage and to disk 
    mutating func store(key: String, _ value: Any) { 
     localValues[key] = value 
     cache.put(key, data: value) 
    } 
} 

然後,LocalCache實例添加到您的類,你可以有很多簡單的getter/setter方法。

class Test { 
    // instance of the local cache 
    var localCache = LocalCache() 

    var enumPropery: MyEnum { 
     get { return localCache.fetch(LocalCache.EnumKey, defaultValue: MyEnum.DefaultValue) } 
     set { localCache.store(LocalCache.EnumKey, newValue) } 
    } 

    var intProperty: Int { 
     get { return localCache.fetch(LocalCache.IntKey, defaultValue: 0) } 
     set { localCache.store(LocalCache.IntKey, newValue) } 
    } 

    var stringProperty: String { 
     get { return localCache.fetch(LocalCache.StringKey, defaultValue: "---") } 
     set { localCache.store(LocalCache.StringKey, newValue) } 
    } 
}