我有一个Objective-C框架,它导出以下类:
@interface NIDIdentifiedNumberItem : NSObject
@property (strong, nonatomic) NSString *name;
@property (strong, nonatomic) NSString *address;
@property (strong, nonatomic) NSString *number;
...
我读到Objective-C指针会自动转换为swift选项,但这不是我所观察到的:
并且以下代码不会产生预期结果:
if item.address != nil
{
// code will execute
如何在Swift中检查Objective-C空指针?
因此在框架中填充对象:
- (NSArray*) identifiedNumbers {
NSMutableArray* numbers = [[NSMutableArray alloc] init];
NIDIdentifiedNumberItem* item = [[NIDIdentifiedNumberItem alloc] init];
item.name = "Something";
item.address = nil;
etc.
[numbers addObject:item];
return numbers;
在Swift中获得:
var identifiedNumbers = []
...
identifiedNumbers = NIDModel.singleton().identifiedNumbers()
...
let item = identifiedNumbers[indexPath.row]
我还观察到以下内容:
let a = item.address
if a != nil {
}
if let b = item.address
{
}
这两个if语句都将执行。赋值后,a的类型为String !!而b是String!类型。为什么它们不同,为什么if语句评估为true?
答案 0 :(得分:2)
问题在于这一行:
var identifiedNumbers = []
您尚未声明这是 的数组。因此, faute de mieux ,它被输入为NSArray。但是NSArray没有已知的元素类型。因此,当你说
时let item = identifiedNumbers[indexPath.row]
你得到一个AnyObject。因此,当您说item.address
时,您不是提取地址;你问这个未知的东西是否有 address
属性。这就是为什么它被输入为String!!
- 第一个!
是因为如果这个东西确实有一个address
它将是一个可选的包裹一个字符串,而第二个是因为整个拥有address
属性的概念将该结果包装在另一个Optional中。
事实证明,这个未知事物确实具有address
属性,因此item.address
不是nil
。但是如果你打开那个,现在你有一个可选字符串,所以现在你可以看到它是否实际上是nil
。它是:
if item.address != nil {
if item.address! != nil {
// it is nil, this won't execute
}
}
如果您正确地键入了identifiedNumbers
[NIDIdentifiedNumberItem]
,那么您将永远不会遇到这些疯狂和不必要的困难。您可以使用Objective-C的轻量级泛型来帮助实现自动化。
答案 1 :(得分:0)
如果您还没有使用NS_ASSUME_NONNULL_BEGIN/END
,那么转换为可选项。所以你可以:
if let address = item.address
{
print("Address is \(address)")
}
如果你告诉编译器假设非null,那么暴露给Swift的类型似乎不是可选的。因此,就Swift而言,它永远不会是nil
。