215

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

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

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

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

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

4

11 回答 11

393

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

于 2009-12-27T01:31:16.670 回答
105

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

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

    NSLog(@"mykey found");
}
于 2013-07-17T23:17:59.997 回答
58

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

if([[NSUserDefaults standardUserDefaults] objectForKey:@"YOUR_KEY"] != nil) {
    ...
}
于 2011-02-10T19:32:59.293 回答
6

斯威夫特 3 / 4:

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

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
于 2016-06-30T05:42:02.443 回答
5

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

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

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

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

于 2013-04-27T19:03:42.777 回答
4

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

extension UserDefaults {

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

// Example
UserDefaults.standard.hasValue(forKey: "username")
于 2017-06-05T21:03:28.370 回答
3

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

这就是我所做的。我在一个名为“_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"]) {
 ...

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

于 2014-01-10T16:22:36.493 回答
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];
    }
}

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

于 2014-03-02T22:27:47.483 回答
3

获取 Swift 版本Bool?

NSUserDefaults.standardUserDefaults().objectForKey(DefaultsIsGiver) as? Bool
于 2016-03-17T17:14:07.923 回答
0

在 Swift3 中,我是这样使用的

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

如果您要多次使用它,答案是很好的

我希望它有帮助:)

于 2017-08-23T04:25:02.560 回答
-1

斯威夫特 3.0

if NSUserDefaults.standardUserDefaults().dictionaryRepresentation().contains({ $0.0 == "Your_Comparison_Key" }){
                    result = NSUserDefaults.standardUserDefaults().objectForKey(self.ticketDetail.ticket_id) as! String
                }
于 2016-08-19T12:17:51.980 回答