iOS - 检查字符串是否为空时的异常

Gee*_*Out 0 xcode objective-c ios ios5

我正在做这样的事情:

// GET THE USER ID
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
NSString *user_id = [standardUserDefaults objectForKey:@"user_id"]; 
Run Code Online (Sandbox Code Playgroud)

然后检查user_id是否为空

if ([user_id length] == 0) {
  proceed = false;
  NSLog(@"Error: User id is not set.");
}
Run Code Online (Sandbox Code Playgroud)

我得到了这个运行时异常:

*由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:' - [__ NSCFBoolean length]:无法识别的选择器发送到实例0x1469f70'

知道为什么我得到例外吗?我不认为我做的事情有什么不妥.

谢谢!

Tom*_*mmy 5

这个:

NSString *user_id = [standardUserDefaults objectForKey:@"user_id"];
Run Code Online (Sandbox Code Playgroud)

返回一个NSNumber(作为NSCFBoolean私有子类NSNumber)而不是字符串.因此它没有实现length,导致异常.

也许你想测试[user_id intValue] > 0?即使你把它转换成一个字符串,它总会有一些长度.

(提出的附带问题:仅仅声明user_id作为对a的引用NSString并不意味着你分配给它的任何东西神奇地变成了一个字符串;实际上没有任何类型的对象类型强制效果.编译器不会抱怨因为NSUserDefaults返回对象类型id,即它保证它们是对象但不对它们的类​​型提出任何声明,并且编译器也不知道.所有对象可以在id不生成警告的情况下进行强制转换,以便可以由类等使用用户默认值NSArray等,只要它是一个对象,它们就可以接受任何东西).

编辑:基于评论中提出的问题,听起来最初存储的东西可能不是字符串.验证Web内容的好方法可能是:

// fall through here if the object isn't a string
if(![responseString isKindOfClass:[NSString class]])
{
    // check whether it's something that can be converted to a string
    if(![responseString respondsToSelector:@selector(stringValue)])
    {
        // some sort of error condition; the server returned something
        // that isn't a string and doesn't convert (in and of itself) to string
    }
    else
    {
        // convert the object to a string
        responseString = [responseString stringValue];
    }
}
Run Code Online (Sandbox Code Playgroud)