iOSシミュレータでは、アプリの起動時にNSUserDefaultから一貫した値を取得できません。私はアプリの以前の実行で値を設定しました(そして私はいくつかのプリントをそこに入れて偶発的な変更がないことを確認しています)ので、私がsynchronize()を呼び出す方法に問題はないとは思わない。私はデフォルト値を設定した後も、メインスレッドでリードが起こっています。数秒後、NSUserDefaultsからのフェッチを再試行すると、正しい値が得られます(タイマーを設定して、値が修正されたことを確認し、起動後も同じ状態を維持するように見えます)。アプリの起動時にNSUserDefaultsの値が一致しない
この値は、ユーザーがデータを(iCloud上またはローカルデバイス上に)保存する場所を表し、ユーザーのデフォルトでは整数で表されます。ここで
class MovingDocument: UIDocument {
enum StorageSettingsState: Int {
case NoChoice = 0
case Local = 1
case ICloud = 2
}
}
アクセスNSUserDefaultsに使用されるクラスの抜粋です::ここで値を表す列挙型です
class Settings {
static let global = Settings()
private enum LocalStoreKeys : String {
case IsHorizontal = "IsHorizontal"
case ItemInPortrait = "ItemInPortrait"
case RotateTitle = "RotateTitle"
case StorageLocation = "StorageLocation"
}
// Other computed variables here for the other settings.
// Computed variable for the storage setting.
var storageLocation: MovingDocument.StorageSettingsState {
get {
print("Storage state fetch: \(NSUserDefaults.standardUserDefaults().integerForKey(LocalStoreKeys.StorageLocation.rawValue))")
return MovingDocument.StorageSettingsState(rawValue: NSUserDefaults.standardUserDefaults().integerForKey(LocalStoreKeys.StorageLocation.rawValue)) ?? .NoChoice
}
set {
print("Setting storage location to \(newValue) (\(newValue.rawValue))")
NSUserDefaults.standardUserDefaults().setInteger(newValue.rawValue, forKey: LocalStoreKeys.StorageLocation.rawValue)
synchronize()
CollectionDocument.settingsChanged()
}
}
func prepDefaultValues() {
NSUserDefaults.standardUserDefaults().registerDefaults([
LocalStoreKeys.IsHorizontal.rawValue: true,
LocalStoreKeys.ItemInPortrait.rawValue: true,
LocalStoreKeys.RotateTitle.rawValue: true,
LocalStoreKeys.StorageLocation.rawValue: MovingDocument.StorageSettingsState.NoChoice.rawValue
])
}
func synchronize() {
NSUserDefaults.standardUserDefaults().synchronize()
}
}
私が読んでする必要がある値(と私は常に起動後に取得するように見えます)値 '1'または.Localです。私がときどき代わりに得ている値は、 '0'か.NoChoice(これはちょうどデフォルト値になります)です。つまり、アプリケーションの起動時に、デフォルト値を使用するように見えます。完全を期すため
は、ここで関連するアプリケーションデリゲートのコードは次のとおり
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
Settings.global.prepDefaultValues() // Must be called before doing CollectionDocument.start() because we need the default value for storage location.
CollectionDocument.start()
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
browserController = ViewController()
navController = UINavigationController(rootViewController: browserController!)
navController!.navigationBar.translucent = false
self.window!.rootViewController = navController
self.window!.makeKeyAndVisible()
checkStorageLocation()
return true
}
ゲッターが(CollectionDocument.start内と呼ばれる)(CollectionDocument場所列挙が定義されているMovingDocumentのサブクラスです)。最後のcheckStorageLocation()への呼び出しは、私の定期的なデバッグであり、記憶場所の値をチェックします(それはdispatch_after()を介してそれ自身を呼び出します)。
私はまた、アプリケーションのコードの大部分(didFinishLaunchingWithOptions ...)をdispatch_async呼び出し(メインスレッド上)に入れてみましたが、違いがあるかどうかを確認しましたデフォルト値とreturn文は直ちに実行され、残りの呼び出しは非同期呼び出しブロックに入れられました)、それでもなお(時には)間違った値が得られました。私はdispatch_afterを代わりに使用してみることができます(そして2〜2秒待機します)が、これが完了するまでアプリを起動することはできません(なぜなら、この1つの問題のローディング画面はばかげているようです。
何が問題になっているかについてのアイデアはありますか?私はNSUserDefaultsの制限について、あなたがそれを読むことが許されている限り、私は気づいていません...
ところで、これはXcodeバージョン7.3.1、iPhone 4sシミュレータのiOSバージョン9.3で発生します。 –
まず、 'synchronize'を呼び出す必要はありません。次に、アプリを実行するたびに' registerDefaults'を使用していますか?現在の値が上書きされます。 – Paulw11
同期は通常は必要ありませんが、私がそれに取り組む前に値を保持しておきたいと思いました(ユーザ値が書き出されるまでに数秒かかることがあります。その特定の設定(残りは遅延アップデートを使用します)に対して安全です。registerDefaultsについては、アプリケーションが起動するたびに呼び出されるはずです。ドキュメント(と私の以前の使用法)。それはちょうど穴を埋める、それは実際の書き込みを無効にすることはできません。 –