【问题标题】:iOS - exception when checking if string is emptyiOS - 检查字符串是否为空时出现异常
【发布时间】:2012-07-26 17:02:28
【问题描述】:

我正在做这样的事情:

// 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”

知道为什么会出现异常吗?我不认为我所做的事情有什么太大的问题。

谢谢!

【问题讨论】:

    标签: objective-c ios xcode ios5


    【解决方案1】:

    这个:

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

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

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

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

    编辑:根据 cmets 中提出的问题,听起来最初存储的东西可能不是字符串。验证网络内容的好方法可能是这样的:

    // 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];
        }
    }
    

    【讨论】:

    • 实际上我想获取实际的 user_id 值,这是我放入的字符串值。从standardUserDefaults获取该字符串的正确方法是什么?谢谢!
    • 我们如何确定user_id 不是NSString 类型?它可以是字母数字或数字字符串。
    • @GeekedOut 如果用户默认存储一个数字,那么您必须存储一个数字。它不会改变类型。只是为了确认一下:user_id 确实是一个局部变量——这不仅仅是您为发布问题所做的快速编辑,是吗?尝试添加NSLog(@"%@", [user_id class])if([user_id isKindOfClass:[NSNumber class]]) NSLog(@"is number") 来说服自己。 @samfisher 引发的异常表明length 发送到的对象类型是NSCFBoolean,这是NSNumber 的私有子类(后者实际上是一个集群)。
    • @Tommy 嗯,我在另一个控制器中设置了 user_id,如下所示: NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults]; [standardUserDefaults setObject:responseString forKey:@"user_id"];
    • @Tommy 如果包含 responseString 的字符串实际上是一个数字,系统是否将它转换为我的数字?我很困惑如何将它设置为字符串,但现在它是一个整数:)
    【解决方案2】:

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

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

    那就这样称呼它吧:

        [myString isBlank];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-28
      • 2015-06-12
      • 1970-01-01
      • 2015-06-05
      • 2014-09-22
      • 1970-01-01
      • 2016-03-20
      相关资源
      最近更新 更多