NSDictionary 如何处理 NIL 对象?
考虑下面的代码。本质上,我们得到 2 个字符串,然后将这些值添加到 NSDictionary 中。
然而,我遇到了一个奇怪的错误。当 fbAccessTokenKey 为 0x0(或 nil)时,也不会添加 twitterToken。
NSString *fbAccessTokenKey=[[UserStockInfo sharedUserStockInfo] getFBAccessTokenKey];
NSString *twitterToken=[[UserStockInfo sharedUserStockInfo] getTwitterAccessTokenKey];
NSDictionary *params= [[NSDictionary alloc] initWithObjectsAndKeys:
fbAccessTokenKey, @"fb_access_token",
twitterToken, @"twitter_access_token",
nil
];
为什么会发生这种情况,有什么好的方法可以解决这个问题?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
nil
用作标记“参数结束”列表的“哨兵”。如果 twitterToken 为 nil,运行时将遍历您的参数,一旦到达 twitterToken,它就会认为它已经到了对象列表的末尾,并且键。这是由于 C/Obj-C 在列表参数方面的实现方式所致。另一种安全的方法是使用 NSMutableDictionary,并检查您的值是否非零,然后将它们添加到可变字典中,如下所示:
有关更多技术信息,有一个很好的方法关于 Cocoa with Love 的文章:http://cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html
nil
is used as a 'sentinel' for marking the "end of arguments" list. IftwitterToken
was nil, the runtime would go through your arguments, and once it got totwitterToken
, 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:For more technical info, there's a good article on Cocoa with Love: http://cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html
您可以使用 NSNull 对象。
文档在这里:
http://开发人员。 apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSNull_Class/Reference/Reference.html
You can use the NSNull object.
Documentation here:
http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSNull_Class/Reference/Reference.html
而不是使用 initWithObjectAndKeys 进行初始化。为什么不实例化一个 NSMutableDictionary 然后添加键值对(如果键为 null 则不添加)?
如果您想从那时起保持它不可变,您可以稍后将其转换回 NSDictionary。
更新
只是回应Josh的评论,我应该澄清一下,当然cast 不会神奇地将参数 NSMutableDictionary 转换为 NSDictionary。但是,如果您将其传递给需要 NSDictionary 的代码,则强制转换将允许您将其视为此类。
乔什的评论包括以下代码:
这将生成以下编译器警告(对我来说,警告会生成错误,编译错误):
Rather than initializing with initWithObjectAndKeys. Why not instantiate an NSMutableDictionary and then add the key value pairs (or not if the key is null)?
You could cast it back to an NSDictionary later if you want to keep it immutable from that point.
Update
Just a note in response to Josh's comment, I should clarify that of course the cast will not magically convert the params NSMutableDictionary to an NSDictionary. But if you are passing it to code which requires an NSDictionary, the cast will let you treat it as such.
Josh's comment includes this code:
This will generate the following compiler warning (and for me, with warnings generating errors, a compile error):