屬性包裹器
(我初二英語水平硬翻,寫的時候國內好像尚未一個統一的叫法。有知道學名的同窗麻煩提醒下我謝啦~)。做用對象
是屬性
主旨
就是:經過property Wrapper
機制,對一些相似的屬性
的實現代碼作同一封裝。propertyWrapper這個知識點不難,比較新而已。只要本身複製下面的Demo在playGround
裏跑一遍看一下就會了。git
但是項目中有不少地方須要UserDefaults保存本地數據,數據量多了這樣的重複代碼
就不少了。github
我把@propertyWrapper 的具體用法和知識點已經寫到了demo中。 PlayGround
中跑一跑就很穩了。swift
當添加新的key去保存數據的時候只用在UserDefaultsConfig 中添加新的屬性
和包裹器
就行app
Over.ide
附:Demo代碼ui
extension UserDefaults {
public enum Keys {
static let hadShownGuideView = "had_shown_guide_view"
}
var hadShownGuideView: Bool {
set {
set(newValue, forKey: Keys.hadShownGuideView)
}
get {
return bool(forKey: Keys.hadShownGuideView)
}
}
}
/// 下面的就是業務代碼了。
let hadShownGuide = UserDefaults.standard.hadShownGuideView
if !hadShownGuide {
/// 顯示新手引導 並保存本地爲已顯示
showGuideView() /// showGuideView具體實現略。
UserDefaults.standard.hadShownGuideView = true
}
複製代碼
@propertyWrapper /// 先告訴編譯器 下面這個UserDefault是一個屬性包裹器
struct UserDefault<T> {
///這裏的屬性key 和 defaultValue 還有init方法都是實際業務中的業務代碼
///咱們不須要過多關注
let key: String
let defaultValue: T
init(_ key: String, defaultValue: T) {
self.key = key
self.defaultValue = defaultValue
}
/// wrappedValue是@propertyWrapper必需要實現的屬性
/// 當操做咱們要包裹的屬性時 其具體set get方法實際上走的都是wrappedValue 的set get 方法。
var wrappedValue: T {
get {
return UserDefaults.standard.object(forKey: key) as? T ?? defaultValue
}
set {
UserDefaults.standard.set(newValue, forKey: key)
}
}
}
///封裝一個UserDefault配置文件
struct UserDefaultsConfig {
///告訴編譯器 我要包裹的是hadShownGuideView這個值。
///實際寫法就是在UserDefault包裹器的初始化方法前加了個@
/// hadShownGuideView 屬性的一些key和默認值已經在 UserDefault包裹器的構造方法中實現
@UserDefault("had_shown_guide_view", defaultValue: false)
static var hadShownGuideView: Bool
}
///具體的業務代碼。
UserDefaultsConfig.hadShownGuideView = false
print(UserDefaultsConfig.hadShownGuideView) // false
UserDefaultsConfig.hadShownGuideView = true
print(UserDefaultsConfig.hadShownGuideView) // true
複製代碼
struct UserDefaultsConfig {
@UserDefault("had_shown_guide_view", defaultValue: false)
static var hadShownGuideView: Bool
///保存用戶名稱
@UserDefault("username", defaultValue: "unknown")
static var username: String
}
複製代碼
最先關於Property Wrapper 的提案:swift-evolution 0258 (特別長一段英文,略略略) Property wrappers to remove boilerplate code in Swift nshipster-propertywrapperspa