Swift - 检查已解包的可选变量是否为nil

7
我有一个模型类,如下所示,它是用Objective-C编写的库。我在我的Swift项目中使用这个类。在Swift中,它变成了类型为String!的属性。有时该属性将为空。因此,我按以下方式测试空值验证:

Vendor.h

@interface Vendor: NSObject {

@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;
@property (nonatomic, strong) NSString *middleName;
}

在我的Swift项目中,我正在检查middleName属性的nil验证,如下所示:
if anObject.middleNam != nil { // Here, It throws runtime error: fatal error: Unexpectedly found nil while unwrapping an Optional value
}

它给我抛出了以下的运行时错误:
fatal error: unexpectedly found nil while unwrapping an Optional value

如果Objective-C属性在Swift中公开为String?,那么我会使用以下代码:
if let middleName = anObject.middleName {

}

我该如何检查未包装的可选变量。
提前致谢。

你可以在隐式解包可选项中使用 if let —— 虽然 != nil 检查应该可以正确处理 middleName,但是 anObject 是如何定义的呢? - Hamish
2个回答

6

如果您希望在Swift中将Objective-C属性作为可选项公开,请使用_Nullable标签进行标记,例如:

@property (nonatomic, strong) NSString * _Nullable middleName;

现在,middleName的名称将是可选类型的String?而不是String!,您可以有条件地解包它。
了解更多关于ObjC中的空值

请注意,OP的属性在Swift中已经作为可选项公开显示(它只是隐式取消包装),他可以对其进行条件取消包装。在Swift 3中,隐式取消包装的可选项与普通可选项完全相同-它只是具有一个属性,告诉编译器在某些情况下可以强制取消包装它。而这些情况不包括nil检查或条件取消包装。对我来说,OP的代码工作得很好-我怀疑他的问题是anObject被定义为IUO并且被强制取消包装了。 - Hamish
尽管我完全同意为 obj-c 类型添加可空标签是一个不错的选择,特别是在与 Swift 进行交互时。 - Hamish
@originaluser2 我同意你的观点。它将被隐式解包为可选类型,他仍然可以对其进行条件解包,但如果您不这样做,编译器不会发出警告,这可能会导致像“let middleName:String = object.middleName”这样的情况崩溃。因此,最好使用可空标记进行标记,这样谁使用它都会得到编译器警告,并且可以安全地处理它。 - Anil Varghese

3

正如 Anil 所提到的,最好的解决方法是编辑你的 Objective-C 代码,加上一些 _Nullable。但是,据我所知,你的 Objective-C 代码是一个你无法编辑的库。因此,你必须处理这些可能为 nilString!

但是,你可以像这样简单地使用 if let 技巧:

if let firstName = vendor.firstName {
    print("Here is my firstName: \(firstName)")
} else {
    print("I have no firstName")
}
if let middleName = vendor.middleName {
    print("Here is my middleName: \(middleName)")
} else {
    print("I have no middleName")
}

if let lastName = vendor.lastName {
    print("Here is my name: \(lastName)")
} else {
    print("I have no lastName")
}

使用此供应商代码,将返回以下结果:
@interface Vendor: NSObject
    @property (nonatomic, strong) NSString *firstName;
    @property (nonatomic, strong) NSString *lastName;
    @property (nonatomic, strong) NSString *middleName;
@end
@implementation Vendor
- (instancetype)init
{
    self = [super init];
    if (self) {
        self.firstName = @"Julien";
        self.middleName = nil;
        self.lastName = @"Quere";
    }

    return self;
}
@end

结果:

Here is my firstName: Julien 
I have no middleName 
Here is my name: Quere

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接