Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does NSDictionary handle NIL objects?

Consider the code below. In essence, we get 2 strings, then we add these values to the NSDictionary.

However, i hit a weird bug. When fbAccessTokenKey is 0x0 (or nil), then twitterToken would not be added as well.

NSString *fbAccessTokenKey=[[UserStockInfo sharedUserStockInfo] getFBAccessTokenKey];
NSString *twitterToken=[[UserStockInfo sharedUserStockInfo] getTwitterAccessTokenKey];

NSDictionary *params= [[NSDictionary alloc] initWithObjectsAndKeys:
                       fbAccessTokenKey, @"fb_access_token", 
                       twitterToken, @"twitter_access_token", 
                       nil
                       ];

Why is this happening, and what is a good way of resolving this?

like image 457
meow Avatar asked Jul 26 '11 03:07

meow


People also ask

Does NSDictionary retain objects?

An NSDictionary will retain it's objects, and copy it's keys. Here are some effects this has had on code I've worked on. Sometimes you get the same object you put in, sometimes not. Immutable objects are optimized to return themselves as a copy .

What is the difference between NSMapTable vs NSDictionary?

NSDictionary / NSMutableDictionary copies keys, and holds strong references to values. NSMapTable is mutable, without an immutable counterpart. NSMapTable can hold keys and values with weak references, in such a way that entries are removed when either the key or value is deallocated.

What is the difference between NSDictionary and NSMutableDictionary?

Main Difference is:NSMutableDictionary is derived from NSDictionary, it has all the methods of NSDictionary. NSMutableDictionary is mutable( can be modified) but NSDictionary is immutable (can not be modified).

What is NSDictionary in Objective-C?

An object representing a static collection of key-value pairs, for use instead of a Dictionary constant in cases that require reference semantics.


2 Answers

nil is used as a 'sentinel' for marking the "end of arguments" list. If twitterToken was nil, the runtime would go through your arguments, and once it got to twitterToken, it would think that it was up to the end of your list of objects and keys. This is due to the way that C/Obj-C is implemented when it comes to list arguments.

The alternative safe way to do it is to use an NSMutableDictionary, and check to see if your values are non-nil, then add them to the mutable dictionary like this:

NSString *fbAccessTokenKey = [[UserStockInfo sharedUserStockInfo] getFBAccessTokenKey];
NSString *twitterToken = [[UserStockInfo sharedUserStockInfo] getTwitterAccessTokenKey];

NSMutableDictionary *params = [NSMutableDictionary dictionary];
if (fbAccessTokenKey) [params setObject:fbAccessTokenKey forKey:@"fb_access_token"];
if (twitterToken) [params setObject:twitterToken forKey:@"twitter_access_token"];

For more technical info, there's a good article on Cocoa with Love: http://cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html

like image 154
Nick Forge Avatar answered Oct 19 '22 23:10

Nick Forge


You can use the NSNull object. Documentation here: http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSNull_Class/Reference/Reference.html

like image 30
albianto Avatar answered Oct 19 '22 23:10

albianto