2017-10-25 15 views
1

変数をUserDefaultsから初期化したい場合は、String?を返し、nilの場合は値を作成して割り当てます。オプションの場合は省略可能な変数を初期化する最良の方法

次のコードは動作しますが、私はそれがString(それはこの段階ではnilすることはできませんので)になりたいしながら、最後に、私のobjString?です。

var obj = UserDefaults.standard.string(forKey: "my_key")// Here, obj is a String? 
if obj == nil { 
    obj = ProcessInfo.processInfo.globallyUniqueString// Returns, a String 
    defaults.set(obj, forKey: "my_key") 
    defaults.synchronize() 
} 
// Here, obj is still a String? 

このような状況では、優れたパターン/ベストプラクティスはありますか?

+1

FYI - [ 'synchronize'を呼び出す必要]がありません(https://stackoverflow.com/questions/40808072/when- and-why-should-you-use-nsuserdefaultss-synchronize-method)を実行します。 – rmaddy

答えて

5

。 クロージャが作成し(ローカルobj 変数を使用して)ユーザのデフォルト値を設定し、それが外側obj変数に割り当てられ ように、発信者に返します。

ます。また、このように、オプションで暗黙的に開封されたを使用することができます
+1

ニートアプローチ。 :) +1 – Hexfire

2

オプションバインド。あなたはそれにhere

let obj: String 

if let string = UserDefaults.standard.string(forKey: "my_key") { 
    obj = string 
} else { 
    obj = ProcessInfo.processInfo.globallyUniqueString 
    UserDefaults.standard.set(obj, forKey: "my_key") 
} 

print(obj) 
+0

'let obj:String'でも可能です。 –

+1

True @MartinRです。 – Hodson

1

使用のいずれかguard letまたはif letを読むことができます。

1)guard let)しかし、あなたのケースのための一般的ではない

guard let obj = UserDefaults.standard.string(forKey: "my_key") else { 
    // guard failed - obj is nil; perform something and return 
    obj = ProcessInfo.processInfo.globallyUniqueString 
    defaults.set(obj, forKey: "my_key") 
    return 
} 

// obj is not nil, you have it at your disposal 
print(obj) 

2)if let

if let obj = UserDefaults.standard.string(forKey: "my_key") { 
    // obj exists 
} else { 
    let obj = ProcessInfo.processInfo.globallyUniqueString 
    defaults.set(obj, forKey: "my_key") 
    print(obj) 
} 

(!)また、実際にコールするもう必要はありませんdefaults.synchronize()

デフォルト・データベース に対する保留中の非同期更新を待機します。このメソッドは不要で、使用しないでください。ユーザーのデフォルトが設定されていない場合は、クロージャが実行される

let obj = UserDefaults.standard.string(forKey: "my_key") ?? { 
    let obj = ProcessInfo.processInfo.globallyUniqueString 
    UserDefaults.standard.set(obj, forKey: "my_key") 
    return obj 
}() 

print(obj) // Type is `String` 

:あなたは "すぐに評価閉鎖" とはnil-合体演算子??を使用することができます

https://developer.apple.com/documentation/foundation/nsuserdefaults/1414005-synchronize

+1

答えを更新するlet letである 'obj'に値を代入しようとしているときに、' let let'の例がうまくいきません。また、 'UserDefaults'から返された値を上書きしようとします。これは要求されたものとは逆です。 – Hodson

+0

あなたは正しいです。十分な注意を払わなかった。正しいでしょう。 – Hexfire

1

var obj: String! = UserDefaults.standard.string(forKey: "my_key")// Here, obj is a (possibly `nil`) `String!` 
if obj == nil { 
    obj = ProcessInfo.processInfo.globallyUniqueString // Returns, a String 
    defaults.set(obj, forKey: "my_key") 
    defaults.synchronize() 
} 

// Here, obj is a non-`nil` `String!`, which will work the same as a `String` 
関連する問題