NSUserDefaults - 如何判断密钥是否存在

时间:2009-12-27 01:24:54

标签: ios objective-c iphone nsuserdefaults

我正在开发一款小型iPhone应用,我使用NSUserDefaults作为我的数据持久性。它只需要跟踪一些事情,比如一些名字和一些数字,所以我想我也可以保持简单。

我找到this page作为参考,但我认为它不能回答我的问题。基本上,我希望能够检查NSUserDefaults中是否已存在值(或密钥),然后相应地执行某些操作。

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

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

这里有些帮助吗?我真的很感激!

11 个答案:

答案 0 :(得分:373)

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

答案 1 :(得分:93)

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

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

    NSLog(@"mykey found");
}

答案 2 :(得分:54)

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

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

答案 3 :(得分:6)

objectForKey如果不存在则返回nil。”如果它确实存在,它也将返回nil,它是一个整数或一个值为零的布尔值(即FALSE或否则为布尔值。

我在5.1和6.1的模拟器中测试了这个。这意味着您无法通过询问“对象”来测试已设置的整数或布尔值。如果你不介意将“未设置”视为“设置为零”,那么你可以为整数逃脱。

已经对此进行过测试的人似乎已被假阴性方面所欺骗,即通过查看objectForKey是否在您知道密钥尚未设置时返回nil进行测试,但未注意到它也返回nil如果key已设置但已设置为NO。

对于我自己的问题,那个发送给我的人,我最后改变了我的布尔语义,以便我所希望的默认值与值设置为NO一致。如果这不是一个选项,你需要存储一个布尔值以外的东西,并确保你可以区分YES,NO和“not set。”

答案 4 :(得分:3)

试试这个小小的烤饼:

-(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];
    }
}

将一切视为对象。似乎对我有用。

答案 5 :(得分:3)

Swift版本获取Bool?

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

答案 6 :(得分:3)

Swift 3/4:

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

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
    }
}

现在它们与其他内置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

答案 7 :(得分:3)

延长UserDefaults一次,不要复制粘贴此解决方案:

extension UserDefaults {

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

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

答案 8 :(得分:2)

我刚刚完成了这一点,并且所有的答案帮助我找到了一个很好的解决方案。我拒绝走上建议的路线,只因为我发现很难阅读和理解。

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

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

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

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

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

然后我将对象用作BOOL:

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

这似乎适用于我的情况。它对我来说更具视觉感受。

答案 9 :(得分:0)

在Swift3中,我以这种方式使用

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

answer非常棒,如果您多次使用它。

我希望它有所帮助:)

答案 10 :(得分:-1)

Swift 3.0

Dataset: Array
(
)

Result: valid
(wrong)

--------------------------------------

Dataset: Array
(
    [childForms] => Array
    (
    )

)

Result: valid
(wrong)

--------------------------------------

Dataset: Array
(
    [childForms] => Array
    (
        [0] => Array
            (
                [fieldA] => 
            )

    )

)

Result: invalid
(correct!)


--------------------------------------

Dataset: Array
(
    [childForms] => Array
    (
        [0] => Array
            (
                [fieldA] => fff
            )

    )

)

Result: valid
(correct!)