比较Objective-C中的版本号

mle*_*cho 83 comparison objective-c

我正在编写一个接收带有项目和版本号的数据的应用程序.数字格式为"1.0.1"或"1.2.5".如何比较这些版本号?我认为他们必须先格式化为字符串,不是吗?我有什么选择来确定"1.2.5"在"1.0.1"之后?

Nat*_*ies 230

这是比较版本的最简单方法,请记住"1"<"1.0"<"1.0.0":

NSString* requiredVersion = @"1.2.0";
NSString* actualVersion = @"1.1.5";

if ([requiredVersion compare:actualVersion options:NSNumericSearch] == NSOrderedDescending) {
  // actualVersion is lower than the requiredVersion
}
Run Code Online (Sandbox Code Playgroud)

  • @ScottBerrevoets我当然希望这不是它的工作方式,因为这意味着"1.2.3"小于"1.1.12"(123 <1112)!正如Apple小心地指出的那样,"[数字_within_字符串使用数值进行比较](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/C/.econst段/ NSNumericSearch)".也就是说,每个字符串中的__sets_将被比较(实质上是`componentsSeparatedByString`方法).您可以使用`@"1.8"`vs` @"1.7.2.3.55"来自己测试一下,并看到1.8出现在前面. (10认同)
  • @Omer:为什么06而不是6?我认为大多数开发人员会认为2.4.06比2.4.4更高. (7认同)
  • 我正在使用这种方法,我最近发现它在比较ie:2.4.06和2.4.4时返回(我认为)错误的结果.我相信2.4.06应该低于2.4.4,但也许我错了......有什么想法吗? (6认同)
  • 这很简单,但依赖于一个非常简单的版本方案. (4认同)
  • NSNumericSearch认为"1.0"小于"1.0.0".对我的目的来说不够灵活. (3认同)

小智 17

我将添加我的方法,它将严格的数字版本(没有a,b,RC等)与任意数量的组件进行比较.

+ (NSComparisonResult)compareVersion:(NSString*)versionOne toVersion:(NSString*)versionTwo {
    NSArray* versionOneComp = [versionOne componentsSeparatedByString:@"."];
    NSArray* versionTwoComp = [versionTwo componentsSeparatedByString:@"."];

    NSInteger pos = 0;

    while ([versionOneComp count] > pos || [versionTwoComp count] > pos) {
        NSInteger v1 = [versionOneComp count] > pos ? [[versionOneComp objectAtIndex:pos] integerValue] : 0;
        NSInteger v2 = [versionTwoComp count] > pos ? [[versionTwoComp objectAtIndex:pos] integerValue] : 0;
        if (v1 < v2) {
            return NSOrderedAscending;
        }
        else if (v1 > v2) {
            return NSOrderedDescending;
        }
        pos++;
    }

    return NSOrderedSame;
}
Run Code Online (Sandbox Code Playgroud)


Don*_*Lea 11

这是对Nathan de Vries的解释,以解决1 <1.0 <1.0.0等问题.

首先,我们可以在我们的版本字符串上解决额外".0"的问题,其中包含以下NSString类别:

@implementation NSString (VersionNumbers)
- (NSString *)shortenedVersionNumberString {
    static NSString *const unnecessaryVersionSuffix = @".0";
    NSString *shortenedVersionNumber = self;

    while ([shortenedVersionNumber hasSuffix:unnecessaryVersionSuffix]) {
        shortenedVersionNumber = [shortenedVersionNumber substringToIndex:shortenedVersionNumber.length - unnecessaryVersionSuffix.length];
    }

    return shortenedVersionNumber;
}
@end
Run Code Online (Sandbox Code Playgroud)

通过上述NSString类别,我们可以缩短版本号以减少不必要的.0

NSString* requiredVersion = @"1.2.0";
NSString* actualVersion = @"1.1.5";

requiredVersion = [requiredVersion shortenedVersionNumberString]; // now 1.2
actualVersion = [actualVersion shortenedVersionNumberString]; // still 1.1.5
Run Code Online (Sandbox Code Playgroud)

现在我们仍然可以使用Nathan de Vries提出的非常简单的方法:

if ([requiredVersion compare:actualVersion options:NSNumericSearch] == NSOrderedDescending) {
  // actualVersion is lower than the requiredVersion
}
Run Code Online (Sandbox Code Playgroud)


uli*_*ess 7

Sparkle(最受欢迎的MacOS软件更新框架)具有SUStandardVersionComparator类,可以实现此目的,还可以考虑构建数和beta标记.即正确比较1.0.5 > 1.0.5b72.0 (2345) > 2.0 (2100).代码只使用Foundation,因此在iOS上也可以正常工作.


小智 7

我自己制作,使用分类..

资源..

@implementation NSString (VersionComparison)
- (NSComparisonResult)compareVersion:(NSString *)version{
    NSArray *version1 = [self componentsSeparatedByString:@"."];
    NSArray *version2 = [version componentsSeparatedByString:@"."];
    for(int i = 0 ; i < version1.count || i < version2.count; i++){
        NSInteger value1 = 0;
        NSInteger value2 = 0;
        if(i < version1.count){
            value1 = [version1[i] integerValue];
        }
        if(i < version2.count){
            value2 = [version2[i] integerValue];
        }
        if(value1  == value2){
            continue;
        }else{
            if(value1 > value2){
                return NSOrderedDescending;
            }else{
                return NSOrderedAscending;
            }
        }
    }
    return NSOrderedSame;
}
Run Code Online (Sandbox Code Playgroud)

测试..

NSString *version1 = @"3.3.1";
NSString *version2 = @"3.12.1";
NSComparisonResult result = [version1 compareVersion:version2];
switch (result) {
    case NSOrderedAscending:
    case NSOrderedDescending:
    case NSOrderedSame:
         break;
    }
Run Code Online (Sandbox Code Playgroud)


小智 6

查看我的NSString类别,该类别在github上实现简单的版本检查; https://github.com/stijnster/NSString-compareToVersion

[@"1.2.2.4" compareToVersion:@"1.2.2.5"];
Run Code Online (Sandbox Code Playgroud)

这将返回一个NSComparisonResult,它比使用更准确;

[@"1.2.2" compare:@"1.2.2.5" options:NSNumericSearch]
Run Code Online (Sandbox Code Playgroud)

还增加了助手;

[@"1.2.2.4" isOlderThanVersion:@"1.2.2.5"];
[@"1.2.2.4" isNewerThanVersion:@"1.2.2.5"];
[@"1.2.2.4" isEqualToVersion:@"1.2.2.5"];
[@"1.2.2.4" isEqualOrOlderThanVersion:@"1.2.2.5"];
[@"1.2.2.4" isEqualOrNewerThanVersion:@"1.2.2.5"];
Run Code Online (Sandbox Code Playgroud)