0

我正在做这样的事情:

// GET THE USER ID
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
NSString *user_id = [standardUserDefaults objectForKey:@"user_id"]; 

然后检查user_id是否为空

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

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

*由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[__NSCFBoolean length]: unrecognized selector sent to instance 0x1469f70”

知道为什么我会得到例外吗?我不认为我所做的事情有什么问题。

谢谢!

4

2 回答 2

5

这个:

NSString *user_id = [standardUserDefaults objectForKey:@"user_id"];

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

也许你想测试[user_id intValue] > 0?即使您将其转换为字符串,它也总会有一些长度。

(提出的附带问题:仅仅声明user_id为 an 的引用NSString并不意味着您分配给它的任何东西都会神奇地变成一个字符串;实际上没有任何类型对象类型强制效果。编译器不会抱怨,因为NSUserDefaults返回的对象type 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];
    }
}
于 2012-07-26T17:06:47.663 回答
1

您收到该错误的原因是您试图在看似布尔值的情况下调用“长度”。无论哪种方式,为了检查字符串是否为空,这里有一些简单的方法,您可以通过类别添加到 NSString 类:

    -(BOOL)isBlank{
        return [[self trim] length]==0;
    }
    -(NSString *)trim{
        return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet] ];
    }

然后调用它只是:

    [myString isBlank];
于 2012-07-26T17:05:36.353 回答