给出以下代码,y不是NSNumber而是NSValue,其结果是在sort()中调用intValue会崩溃。排序NSNumber数组的解决方案是什么NSNumber是从字符串创建的?
var theArray: Array<NSNumber> = []
let x = NSNumber(2067876748)
let y = NSNumber(nonretainedObject: Int("2056787657"))
theArray.append(x)
theArray.append(y)
theArray.sort { (a:NSNumber, b:NSNumber) -> Bool in
let aintval = a.intValue
let binvval = b.intValue
您不需要从Int
初始化NSNumber
s只是为了将它们传递给Obj-C。Swift的数字类型被桥接到NSNumber
,所以你可以简单地使用类型转换操作符来转换它们。
let intArray = [2067876748, Int("2056787657")].compactMap { $0 }
let nsNumberArray = intArray as Array<NSNumber>
在你的Swift代码中,你应该坚持使用Swift类型,让Swift为你桥接到NSNumber
的NSArray
:
var array: [Int] = []
let x = 2067876748
array.append(x)
if let y = Int("2056787657") {
array.append(y)
}
array.sort()
foo.bar(array) // this is objc method defined below
因此,想象一个Objective-C的方法:
@implementation Foo
- (void)bar:(NSArray *)array {
NSLog(@"Whole array: %@", array);
for (long i = 0; i < array.count; i++) {
NSNumber *value = array[i];
BOOL isNSNumber = [value isKindOfClass:[NSNumber class]];
NSLog(@"Item %ld is %@, which %@ a NSNumber.", i, value, isNSNumber ? @"is" : @"is not");
}
}
@end
结果是:
2021-03-02 12:50:23.284723-0800 MyApp[9473:3742305]整个数组:(2056787657,2067876748(MyApp[9473:3742305]项目0为2056787657,是NSNumber。MyApp[9473:3742305]项目1为2067876748,是NSNumber。
讽刺的是,如果Objective-C代码使用轻量级泛型,你只需要明确桥接。如考虑:
NS_ASSUME_NONNULL_BEGIN
@interface Foo : NSObject
- (void)bar:(NSArray <NSNumber *> *)array;
@end
NS_ASSUME_NONNULL_END
那么当你从Swift调用它时,你需要明确:
let array: [Int] = ...
foo.bar(array as [NSNumber])
但是这个故事的寓意是,除非绝对必要,否则一般不应该在Swift代码中使用NS
类型。例如,如果数组很大,或者你需要NSMutableArray
或其他特殊的东西,那么你可以继续使用NS
。但是不要为了某些Objective-C库/类而过早地使你的Swift代码复杂化,因为它为我们优雅地完成了这种桥接。