问题人生[20160713] - NSString 之 longValue

前段时间帮同事解决一堆闪退的bug,遇到一个很诡异的问题,其实这么多的bug的问题都是相同的,那就是字符串与数值转换。


我们看一个例子

    NSString *num01 = @"105";
    
    long num11 = [num01 longValue];
    
    NSLog(@"num11: %ld", num11);

其实这段代码是无法通过编译的,因为我们看到了红色的叉叉及错误信息

No visible @interface for 'NSString' declares the selector 'longValue'

意思很明显,NSString 并没有 longValue 这个方法,所以这个bug本不应该出现在已经打包成功的程序中,但事实上,他确实是有可能存在的。

因为还有另外一种情况:大多数时候,我们的数据并非本地产生的,而是来源于服务器,来源于网络,而网络数据多通过JSON发回,然后转化为字典,则可能出现了下面的情况:

    NSString *num02 = @"105";
    NSDictionary *dict = @{@"num02": num02};
    
    long num12 = [[dict objectForKey: @"num02"] longValue];
    
    NSLog(@"num12: %ld", num12);

因为从字典中获取的对象,Xcode并不知道其类型,所以无法检查其是否有longValue这个方法,故这段代码能够顺利编译通过。然而,躲得过初一,不见得能躲得过十五,出来混迟早是要还滴,一旦代码运行到第三行,app就华丽丽滴闪退了,这就是bug产生的原因。

我不知道当初写代码的人是否从来就没有自测过,也没兴趣去研究是否在老版本的Xcode或iOS系统中这个闪退不会发生,既然这个bug现在发生了,就要找到原因。

其实原因很简单:在Objective-C中确实存在 longValue这个方法,所以才能通过Xcode的检查机制,然而,这个方法却不是NSString的,而是属于NSNumber的,通过查询API文档发现,在iOS9.2中,NSNumber有以下属性:

@property (readonly) char charValue;
@property (readonly) unsigned char unsignedCharValue;
@property (readonly) short shortValue;
@property (readonly) unsigned short unsignedShortValue;
@property (readonly) int intValue;
@property (readonly) unsigned int unsignedIntValue;
@property (readonly) long longValue;
@property (readonly) unsigned long unsignedLongValue;
@property (readonly) long long longLongValue;
@property (readonly) unsigned long long unsignedLongLongValue;
@property (readonly) float floatValue;
@property (readonly) double doubleValue;
@property (readonly) BOOL boolValue;
@property (readonly) NSInteger integerValue NS_AVAILABLE(10_5, 2_0);
@property (readonly) NSUInteger unsignedIntegerValue NS_AVAILABLE(10_5, 2_0);

@property (readonly, copy) NSString *stringValue;

而 NSString 的属性只有:

@property (readonly) double doubleValue;
@property (readonly) float floatValue;
@property (readonly) int intValue;
@property (readonly) NSInteger integerValue NS_AVAILABLE(10_5, 2_0);
@property (readonly) long long longLongValue NS_AVAILABLE(10_5, 2_0);
@property (readonly) BOOL boolValue NS_AVAILABLE(10_5, 2_0); 

由此可以看出,NSString 确实没有 longValue 方法,所以可以使用 longLongValue来代替longValue就可以解决这个bug了。




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NSString类是iOS开发中非常常用的字符串类,其中substringFromIndex、substringWithRange和substringToIndex是NSString类中的三个常用方法,用于截取字符串的一部分。下面分别介绍它们的使用方法。 1. substringFromIndex方法 该方法用于截取字符串从指定位置到字符串结尾的所有字符,返回截取后的字符串。它的方法签名如下: ``` - (NSString *)substringFromIndex:(NSUInteger)from; ``` 其中,from是一个NSUInteger类型的参数,表示要截取的起始位置,从0开始计数。 示例代码: ``` NSString *str = @"Hello World"; NSString *subStr = [str substringFromIndex:6]; NSLog(@"%@", subStr); // 输出:"World" ``` 2. substringWithRange方法 该方法用于截取字符串从指定范围内的所有字符,返回截取后的字符串。它的方法签名如下: ``` - (NSString *)substringWithRange:(NSRange)range; ``` 其中,range是一个NSRange类型的结构体,用来指定要截取的字符串的范围。 示例代码: ``` NSString *str = @"Hello World"; NSRange range = NSMakeRange(6, 5); NSString *subStr = [str substringWithRange:range]; NSLog(@"%@", subStr); // 输出:"World" ``` 3. substringToIndex方法 该方法用于截取字符串从字符串开头到指定位置的所有字符,返回截取后的字符串。它的方法签名如下: ``` - (NSString *)substringToIndex:(NSUInteger)to; ``` 其中,to是一个NSUInteger类型的参数,表示要截取的结束位置,从0开始计数。 示例代码: ``` NSString *str = @"Hello World"; NSString *subStr = [str substringToIndex:5]; NSLog(@"%@", subStr); // 输出:"Hello" ``` 以上就是NSString中substringFromIndex、substringWithRange和substringToIndex方法的使用方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值