В общем случае лучше спросить, может ли объект выполнить данный селектор, чем проверять номер версии, чтобы решить, должен ли он присутствовать.
Когда это не вариант, вам нужно быть здесь немного осторожнее, потому что [@"5.0" compare:@"5" options:NSNumericSearch]
возвращает NSOrderedDescending
, что вполне может быть и вовсе не предназначено; Я мог бы ожидать NSOrderedSame
здесь. По крайней мере, это теоретическая проблема, от которой, на мой взгляд, стоит защищаться.
Также стоит учесть возможность ввода неверной версии, которую нельзя сравнивать. Apple предоставляет три предопределенные константы NSOrderedAscending
, NSOrderedSame
и NSOrderedDescending
, но я могу подумать об использовании некоторой вещи, называемой NSOrderedUnordered
, если я не могу сравнить две вещи и хочу вернуть значение, указывающее на это .
Более того, не исключено, что Apple когда-нибудь расширит свои три предопределенные константы, чтобы разрешить различные возвращаемые значения, что делает сравнение != NSOrderedAscending
неразумным.
С учетом сказанного рассмотрим следующий код.
typedef enum {kSKOrderedNotOrdered = -2, kSKOrderedAscending = -1, kSKOrderedSame = 0, kSKOrderedDescending = 1} SKComparisonResult;
@interface SKComparator : NSObject
+ (SKComparisonResult)comparePointSeparatedVersionNumber:(NSString *)vOne withPointSeparatedVersionNumber:(NSString *)vTwo;
@end
@implementation SKComparator
+ (SKComparisonResult)comparePointSeparatedVersionNumber:(NSString *)vOne withPointSeparatedVersionNumber:(NSString *)vTwo {
if (!vOne || !vTwo || [vOne length] < 1 || [vTwo length] < 1 || [vOne rangeOfString:@".."].location != NSNotFound ||
[vTwo rangeOfString:@".."].location != NSNotFound) {
return SKOrderedNotOrdered;
}
NSCharacterSet *numericalCharSet = [NSCharacterSet characterSetWithCharactersInString:@".0123456789"];
NSString *vOneTrimmed = [vOne stringByTrimmingCharactersInSet:numericalCharSet];
NSString *vTwoTrimmed = [vTwo stringByTrimmingCharactersInSet:numericalCharSet];
if ([vOneTrimmed length] > 0 || [vTwoTrimmed length] > 0) {
return SKOrderedNotOrdered;
}
NSArray *vOneArray = [vOne componentsSeparatedByString:@"."];
NSArray *vTwoArray = [vTwo componentsSeparatedByString:@"."];
for (NSUInteger i = 0; i < MIN([vOneArray count], [vTwoArray count]); i++) {
NSInteger vOneInt = [[vOneArray objectAtIndex:i] intValue];
NSInteger vTwoInt = [[vTwoArray objectAtIndex:i] intValue];
if (vOneInt > vTwoInt) {
return kSKOrderedDescending;
} else if (vOneInt < vTwoInt) {
return kSKOrderedAscending;
}
}
if ([vOneArray count] > [vTwoArray count]) {
for (NSUInteger i = [vTwoArray count]; i < [vOneArray count]; i++) {
if ([[vOneArray objectAtIndex:i] intValue] > 0) {
return kSKOrderedDescending;
}
}
} else if ([vOneArray count] < [vTwoArray count]) {
for (NSUInteger i = [vOneArray count]; i < [vTwoArray count]; i++) {
if ([[vTwoArray objectAtIndex:i] intValue] > 0) {
return kSKOrderedAscending;
}
}
}
return kSKOrderedSame;
}
@end