ios NSUserDefaults - 如何判断一个键是否存在

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1964873/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:43:30  来源:igfitidea点击:

NSUserDefaults - How to tell if a key exists

iosobjective-ciphonensuserdefaults

提问by Ethan Mick

I'm working on a small iPhone app, and I am using NSUserDefaultsas my data persistence. It only has to keep track of a few things, such as some names and some numbers so I figure I might as well keep it simple.

我正在开发一个小型 iPhone 应用程序,并将其NSUserDefaults用作我的数据持久性。它只需要跟踪一些事情,比如一些名字和一些数字,所以我想我最好保持简单。

I found this pagefor some reference, but I don't think it can answer my question. Basically, I want to be able to check if a value (or a key) already exists in the NSUserDefaultsand then do something accordingly.

我找到了这个页面作为参考,但我认为它不能回答我的问题。基本上,我希望能够检查一个值(或一个键)是否已经存在于 中NSUserDefaults,然后相应地做一些事情。

Some examples: The app starts up, if this is the first time it starts up it outputs an alert saying welcome. To tell if this is first time it has opened it reads the UserDefaultsand checks.

一些示例: 应用程序启动,如果这是第一次启动,它会输出一条警报,表示欢迎。要判断这是否是第一次打开,它会读取UserDefaults并检查。

Example 2: It says, "Hello [Name]", where Name is something you have entered. If you have opened the app and there is no name, it should say "Hello World." I need to check if you have entered a name already and act accordingly. The name would be stored in NSUserDefaults.

示例 2:它说,“Hello [Name]”,其中 Name 是您输入的内容。如果您打开了应用程序并且没有名称,它应该会显示“Hello World”。我需要检查你是否已经输入了一个名字并采取相应的行动。该名称将存储在NSUserDefaults.

Some help here? I'd really appreciate it!

一些帮助?我真的很感激!

回答by jspcal

objectForKey:will return nilif it doesn't exist.

objectForKey:nil如果它不存在,将返回。

回答by i.jameelkhan

As mentioned above it wont work for primitive types where 0/NO could be a valid value. I am using this code.

如上所述,它不适用于 0/NO 可能是有效值的原始类型。我正在使用此代码。

NSUserDefaults *defaults= [NSUserDefaults standardUserDefaults];
if([[[defaults dictionaryRepresentation] allKeys] containsObject:@"mykey"]){

    NSLog(@"mykey found");
}

回答by mirap

The objectForKey:method will return nilif the value does not exist. Here's a simple IF / THEN test that will tell you if the value is nil:

如果该值不存在,该objectForKey:方法将返回nil。这是一个简单的 IF / THEN 测试,它会告诉您值是否为零:

if([[NSUserDefaults standardUserDefaults] objectForKey:@"YOUR_KEY"] != nil) {
    ...
}

回答by JamesKVL

"objectForKey will return nil if it doesn't exist." It will also return nil if it does exist and it is either an integer or a boolean with a value of zero (i.e. FALSE or NO for the boolean).

objectForKey 如果不存在则返回 nil。” 如果它确实存在并且它是整数或值为 0 的布尔值(即布尔值的 FALSE 或 NO),它也将返回 nil。

I've tested this in the simulator for both 5.1 and 6.1. This means that you cannot really test for either integers or booleans having been set by asking for "the object". You can get away with this for integers if you don't mind treating "not set" as if it were "set to zero".

我已经在模拟器中对 5.1 和 6.1 进行了测试。这意味着您无法真正测试通过请求“对象”来设置的整数或布尔值。如果您不介意将“未设置”视为“设置为零”,则可以对整数使用此方法。

The people who already tested this appear to have been fooled by the false negative aspect, i.e. testing this by seeing if objectForKey returns nil when you know the key hasn't been set but failing to notice that it also returns nil if the key has been set but has been set to NO.

已经测试过这个的人似乎被假阴性方面愚弄了,即通过查看 objectForKey 在您知道尚未设置密钥时是否返回 nil 来测试这一点,但没有注意到如果密钥已被设置,它也会返回 nil设置但已设置为 NO。

For my own problem, that sent me here, I just ended up changing the semantics of my boolean so that my desired default was in congruence with the value being set to NO. If that's not an option, you'll need to store as something other than a boolean and make sure that you can tell the difference between YES, NO, and "not set."

对于我自己的问题,将我发送到这里,我只是最终更改了布尔值的语义,以便我想要的默认值与设置为 NO 的值一致。如果这不是一个选项,您将需要存储为布尔值以外的其他内容,并确保您可以区分 YES、NO 和“未设置”之间的区别。

回答by stef

Swift 3 / 4:

斯威夫特 3 / 4:

Here is a simple extension for Int/Double/Float/Bool key-value types that mimic the Optional-return behavior of the other types accessed through UserDefaults.

这是 Int/Double/Float/Bool 键值类型的一个简单扩展,它模仿了通过 UserDefaults 访问的其他类型的 Optional-return 行为。

(Edit Aug 30 2018:Updated with more efficient syntax from Leo's suggestion.)

编辑 2018 年 8 月 30 日:根据 Leo 的建议使用更有效的语法进行了更新。)

extension UserDefaults {
    /// Convenience method to wrap the built-in .integer(forKey:) method in an optional returning nil if the key doesn't exist.
    func integerOptional(forKey: String) -> Int? {
        return self.object(forKey: forKey) as? Int
    }
    /// Convenience method to wrap the built-in .double(forKey:) method in an optional returning nil if the key doesn't exist.
    func doubleOptional(forKey: String) -> Double? {
        return self.object(forKey: forKey) as? Double
    }
    /// Convenience method to wrap the built-in .float(forKey:) method in an optional returning nil if the key doesn't exist.
    func floatOptional(forKey: String) -> Float? {
        return self.object(forKey: forKey) as? Float
    }
    /// Convenience method to wrap the built-in .bool(forKey:) method in an optional returning nil if the key doesn't exist.
    func boolOptional(forKey: String) -> Bool? {
        return self.object(forKey: forKey) as? Bool
    }
}

They are now more consistent alongside the other built-in get methods (string, data, etc.). Just use the get methods in place of the old ones.

它们现在与其他内置 get 方法(字符串、数据等)更加一致。只需使用 get 方法代替旧的方法。

let AppDefaults = UserDefaults.standard

// assuming the key "Test" does not exist...

// old:
print(AppDefaults.integer(forKey: "Test")) // == 0
// new:
print(AppDefaults.integerOptional(forKey: "Test")) // == nil

回答by pepelkod

Try this little crumpet:

试试这个小松饼:

-(void)saveUserSettings{
NSNumber*   value;

value = [NSNumber numberWithFloat:self.sensativity];
[[NSUserDefaults standardUserDefaults] setObject:value forKey:@"sensativity"];
}
-(void)loadUserSettings{
    NSNumber*   value;
    value = [[NSUserDefaults standardUserDefaults] objectForKey:@"sensativity"];
    if(value == nil){
        self.sensativity = 4.0;
    }else{
        self.sensativity = [value floatValue];
    }
}

Treat everything as an object. Seems to work for me.

把一切都当作一个对象。似乎对我有用。

回答by Ben

Swift version to get Bool?

Swift 版本获取 Bool?

NSUserDefaults.standardUserDefaults().objectForKey(DefaultsIsGiver) as? Bool

回答by mbelsky

Extend UserDefaultsonce to don't copy-paste this solution:

扩展UserDefaults一次不要复制粘贴此解决方案:

extension UserDefaults {

    func hasValue(forKey key: String) -> Bool {
        return nil != object(forKey: key)
    }
}

// Example
UserDefaults.standard.hasValue(forKey: "username")

回答by james Burns

I just went through this, and allof your answers helped me toward a good solution, for me. I resisted going the route suggested by, just because I found it hard to read and comprehend.

我刚刚经历了这个,你的所有答案都帮助我找到了一个很好的解决方案,对我来说。我拒绝走建议的路线,只是因为我觉得很难阅读和理解。

Here's what I did. I had a BOOL being carried around in a variable called "_talkative".

这就是我所做的。我在一个名为“_talkative”的变量中携带了一个 BOOL。

When I set my default (NSUserDefaults) object, I set it as an object,as I could then test to see if it was nil:

当我设置我的默认 (NSUserDefaults) 对象时,我将它设置为一个对象,因为我可以测试它是否为nil:

//converting BOOL to an object so we can check on nil
[defaults setObject:@(_talkative) forKey:@"talkative"];

Then when I went to see if it existed, I used:

然后当我去看它是否存在时,我使用了:

if ([defaults objectForKey:@"talkative"]!=nil )
  {

Then I used the object as a BOOL:

然后我将该对象用作 BOOL:

if ([defaults boolForKey:@"talkative"]) {
 ...

This seems to work in my case. It just made more visual sense to me.

这在我的情况下似乎有效。这对我来说只是更具视觉意义。

回答by Nikhil Manapure

In Swift3, I have used in this way

在Swift3中,我是这样使用的

var hasAddedGeofencesAtleastOnce: Bool {
    get {
        return UserDefaults.standard.object(forKey: "hasAddedGeofencesAtleastOnce") != nil
    }
}

The answeris great if you are to use that multiple times.

答案,如果你是使用多次是巨大的。

I hope it helps :)

我希望它有帮助:)