NSUserDefaults - How to tell if a key exists

前端 未结 11 1721
耶瑟儿~
耶瑟儿~ 2020-12-12 11:06

I\'m working on a small iPhone app, and I am using NSUserDefaults as my data persistence. It only has to keep track of a few things, such as some names and som

相关标签:
11条回答
  • 2020-12-12 11:40

    Swift 3.0

    if NSUserDefaults.standardUserDefaults().dictionaryRepresentation().contains({ $0.0 == "Your_Comparison_Key" }){
                        result = NSUserDefaults.standardUserDefaults().objectForKey(self.ticketDetail.ticket_id) as! String
                    }
    
    0 讨论(0)
  • 2020-12-12 11:43

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

    NSUserDefaults *defaults= [NSUserDefaults standardUserDefaults];
    if([[[defaults dictionaryRepresentation] allKeys] containsObject:@"mykey"]){
    
        NSLog(@"mykey found");
    }
    
    0 讨论(0)
  • 2020-12-12 11:44

    I just went through this, and all of 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".

    When I set my default (NSUserDefaults) object, I set it as an object, as I could then test to see if it was 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:

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

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

    0 讨论(0)
  • 2020-12-12 11:46

    objectForKey: will return nil if it doesn't exist.

    0 讨论(0)
  • 2020-12-12 11:48

    "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).

    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".

    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.

    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."

    0 讨论(0)
  • 2020-12-12 11:50

    Extend UserDefaults once to don't copy-paste this solution:

    extension UserDefaults {
    
        func hasValue(forKey key: String) -> Bool {
            return nil != object(forKey: key)
        }
    }
    
    // Example
    UserDefaults.standard.hasValue(forKey: "username")
    
    0 讨论(0)
提交回复
热议问题