一直都在用着Three20库中的系统版本判断方法都是挺正常的,一直到iOS10的出现,它竟然直接就把我往坑里推了。先来看这样的一段代码:
if ([Utils versionStringCompare:@"9.0"] != NSOrderedAscending)
{
//do something...
}
代码原意是在9.0版本以上要做相应的操作,结果在iOS 10下竟然不走里面的逻辑,经过调试发现返回的值竟然是NSOrderedAscending。于是,不多说直接看比较版本方法的实现代码:
- (NSComparisonResult)versionStringCompare:(NSString *)other
{
NSArray *oneComponents = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"a"];
NSArray *twoComponents = [other componentsSeparatedByString:@"a"];
// The parts before the "a"
NSString *oneMain = [oneComponents objectAtIndex:0];
NSString *twoMain = [twoComponents objectAtIndex:0];
// If main parts are different, return that result, regardless of alpha part
NSComparisonResult mainDiff;
if ((mainDiff = [oneMain compare:twoMain]) != NSOrderedSame)
{
return mainDiff;
}
// At this point the main parts are the same; just deal with alpha stuff
// If one has an alpha part and the other doesn't, the one without is newer
if ([oneComponents count] < [twoComponents count])
{
return NSOrderedDescending;
}
else if ([oneComponents count] > [twoComponents count])
{
return NSOrderedAscending;
}
else if ([oneComponents count] == 1)
{
// Neither has an alpha part, and we know the main parts are the same
return NSOrderedSame;
}
// At this point the main parts are the same and both have alpha parts. Compare the alpha parts
// numerically. If it's not a valid number (including empty string) it's treated as zero.
NSNumber *oneAlpha = [NSNumber numberWithInt:[[oneComponents objectAtIndex:1] intValue]];
NSNumber *twoAlpha = [NSNumber numberWithInt:[[twoComponents objectAtIndex:1] intValue]];
return [oneAlpha compare:twoAlpha];
}
看了这代码我汗了。。。原来里面的版本判断竟然是直接用字符串比较的(Facebook的工程师,偶太信得过你们了。),难怪“9”会比“10”要大??。没有办法了,只能对其进行改造,改造结果如下:
+ (NSInteger)versionCompare:(NSString *)other
{
NSArray *oneComponents = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"a"];
NSArray *twoComponents = [other componentsSeparatedByString:@"a"];
NSArray *oneVerComponents = nil;
NSArray *twoVerComponents = nil;
if (oneComponents.count > 0)
{
oneVerComponents = [oneComponents[0] componentsSeparatedByString:@"."];
}
if (twoComponents.count > 0)
{
twoVerComponents = [twoComponents[0] componentsSeparatedByString:@"."];
}
__block NSComparisonResult mainDiff = NSOrderedSame;
[oneVerComponents enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSInteger oneVer = [obj integerValue];
if (twoVerComponents.count > idx)
{
NSInteger twoVer = [twoVerComponents[idx] integerValue];
if (oneVer > twoVer)
{
mainDiff = NSOrderedDescending;
*stop = YES;
}
else if (oneVer < twoVer)
{
mainDiff = NSOrderedAscending;
*stop = YES;
}
}
else
{
mainDiff = NSOrderedDescending;
*stop = YES;
}
}];
if (mainDiff != NSOrderedSame)
{
return mainDiff;
}
if (oneVerComponents.count < twoVerComponents.count)
{
//比较版本号比设备版本号多一个子版本部分的时候,证明比较版本号的版本较高
return NSOrderedAscending;
}
// At this point the main parts are the same; just deal with alpha stuff
// If one has an alpha part and the other doesn't, the one without is newer
if ([oneComponents count] < [twoComponents count])
{
return NSOrderedDescending;
}
else if ([oneComponents count] > [twoComponents count])
{
return NSOrderedAscending;
}
else if ([oneComponents count] == 1)
{
// Neither has an alpha part, and we know the main parts are the same
return NSOrderedSame;
}
// At this point the main parts are the same and both have alpha parts. Compare the alpha parts
// numerically. If it's not a valid number (including empty string) it's treated as zero.
NSNumber *oneAlpha = [NSNumber numberWithInt:[[oneComponents objectAtIndex:1] intValue]];
NSNumber *twoAlpha = [NSNumber numberWithInt:[[twoComponents objectAtIndex:1] intValue]];
return [oneAlpha compare:twoAlpha];
}
OK,测试返回正常,还是杠杠的?