2016-03-19 69 views
1

我有每次被設定的時間用戶寫入SharedPreferences類:忽略setter和設置屬性直接

class UserManager @Inject constructor(
     val prefs: SharedPreferences, 
     val jsonAdapter: JsonAdapter<User> 
    ) { 

    companion object { 
     val USER = "user" 
    } 

    var user: User = User() 
     set(value) { 
      field = value 
      prefs.edit().putString(USER, jsonAdapter.toJson(user)).apply() 
     } 

    init { 
     val userString = prefs.getString(USER, null) 
     if (userString != null) { 
      user = jsonAdapter.fromJson(userString) 
     } 
    } 
} 

問題:如果用戶在初始化模塊組,它調用的二傳手並將剛剛從共享首選項獲得的用戶寫入共享的首選項。

問題1:如何直接從init塊設置屬性?

問題2:爲什麼我在定義自定義設置器時必須初始化用戶,但在使用默認設置器時可以省略初始化?

回答

3

。您可以使用run功能從STDLIB做到這一點:

class UserManager @Inject constructor(
     val prefs: SharedPreferences, 
     val jsonAdapter: JsonAdapter<User> 
) { 

    companion object { 
     val USER = "user" 
    } 

    var user: User = run { 
     val userString = prefs.getString(USER, null) 
     if (userString != null) { 
      jsonAdapter.fromJson(userString) 
     } else { 
      User() 
     } 
    } 
     set(value) { 
      field = value 
      prefs.edit().putString(USER, jsonAdapter.toJson(user)).apply() 
     } 
} 
在科特林松弛提出伊利亞Ryzhenkov

較短的語法:

var user: User = prefs.getString(USER, null)?.let { jsonAdapter.fromJson(it) } ?: User() 
    set(value) { 
     field = value 
     prefs.edit().putString(USER, jsonAdapter.toJson(user)).apply() 
    } 
1

我認爲最好的解決辦法是使用這裏所描述的「支持財產」的概念:https://kotlinlang.org/docs/reference/properties.html#backing-properties

private var _table: Map<String, Int>? = null 
public val table: Map<String, Int> 
    get() { 
    if (_table == null) 
     _table = HashMap() // Type parameters are inferred 
    return _table ?: throw AssertionError("Set to null by another thread") 
    } 

然後在構造函數初始化後盾財產和做的<backingproperty> = value代替field = value以及點的吸氣劑支持屬性。

+0

我測試了這一點,它的工作原理卻II找到基里爾的解決方案的更多可讀。仍然有一個upvote。 – Kuno