1、缘起:
在排查一个古老的版本上的bug时,定位到一处诡异的代码。
2、复现:
a)
NSString *contentType = nil;
NSRange range = [contentType rangeOfString:@"ssx:="];
if(range.location != NSNotFound) {
NSLog(@"====aaa");
}
//(NSRange) range = location=0, length=0
b)
NSString *contentType = @":\u4809";
NSRange range = [contentType rangeOfString:@":"];
if(range.location != NSNotFound) {
NSLog(@"====aaa");
}
c)
NSString *contentType = @"asad";
NSRange range = [contentType rangeOfString:@"ssx:="];
if(range.location != NSNotFound) {
NSLog(@"====aaa");
}
//(NSRange) range = location=9223372036854775807, length=0
d)
NSString *contentType = @"xasd";
NSRange range = [contentType rangeOfString:@""];
if(range.location != NSNotFound) {
NSLog(@"====aaa");
}
//(NSRange) range = location=9223372036854775807, length=0
3、官宣:
Return Value
An NSRange structure giving the location and length in the receiver of the first occurrence of searchString. Returns {NSNotFound, 0} if searchString is not found or is empty ("").
官方文档指出:当搜索的字符串没有找到或者搜索的字符循环是空("",这里不要理解成" "后者是空格)时,会返回{NSNotFound,0}。
这里有一点需要重点提的是:如果NSRange range = [targetString rangeOfString:@"xxxxx"];
中targetString是nil时。range的值是{0,0}也就是初始化的默认值。
上面提到的第二点绝对是一个陷阱,有很多代码都包含了这个风险。ex:
NSString *contentType = allResponseHeader[@"Content_type"];
if([contentType rangeOfString:@"ssx:="].location != NSNotFound) {//这个使用包含风险
//do something
}
这段代码本意是要判断conten_type如果包含了“ssx:=”字符串时,在执行下面的操作,但是没有考虑当content_type为nil时,这个判断是成立的,因为这时返回的NSRange是{0,0} !!!这种用法都是照搬了网上的代码,无脑使用,千万要注意!!!
网友评论