Swift - проверить ноль развернутой дополнительной переменной

У меня есть следующий класс модели, который находится в библиотеке, написанной на Objective-C. Я использую этот класс в своем быстром проекте. В Swift это становится свойством типа String!. Иногда это свойство будет нулевым. Итак, я проверяю нулевую проверку следующим образом:

Поставщик.h

@interface Vendor: NSObject {

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

В моем проекте Swift я проверяю нулевую проверку свойства middleName, как показано ниже:

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 {

}

Как мне проверить развернутую необязательную переменную.

Заранее спасибо.


person Shanmugaraja G    schedule 28.06.2016    source источник
comment
Вы можете использовать if let с неявно развернутыми опциями — хотя проверка != nil должна правильно работать с middleName, как определяется anObject?   -  person Hamish    schedule 28.06.2016


Ответы (2)


Если вы хотите, чтобы свойство ObjectiveC отображалось в Swift как необязательное, отметьте его тегом _Nullable, например

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

Теперь имя middleName будет необязательным для типа String? вместо String!, и вы можете условно развернуть его.

Подробнее об обнулении в ObjC

person Anil Varghese    schedule 28.06.2016
comment
Обратите внимание, что свойство OP уже представлено в Swift как необязательное (оно просто неявно разворачивается), и он может использовать для него условную разворачивание. В Swift 3 неявно развернутый необязательный элемент — это тот же тип, что и обычный необязательный — у него просто есть атрибут, сообщающий компилятору, что у него есть возможность принудительно развернуть его в определенных ситуациях. И эти ситуации не включают nil проверки или условную распаковку. Код OP у меня работает нормально - я подозреваю, что его проблема в том, что anObject определяется как IUO, и это то, что разворачивается силой. - person Hamish; 28.06.2016
comment
Хотя я определенно согласен с тем, что добавление тегов nullability к типам obj-c — это хороший способ, особенно при взаимодействии со Swift. - person Hamish; 28.06.2016
comment
@originaluser2 Я согласен с вашей точкой зрения. он будет неявно развёрнут необязательным, и он по-прежнему может использовать для него условную развёртку, но компилятор не будет жаловаться, если вы этого не сделаете, и это вызовет сбой в таких ситуациях, как ``let middleName:String = object.middleName`. Поэтому хорошей практикой является пометка тегом, допускающим значение NULL, поэтому тот, кто когда-либо будет его использовать, получит предупреждение компилятора, и он сможет безопасно с ним справиться. - person Anil Varghese; 28.06.2016

Как упомянул Анил, лучшим решением было бы отредактировать код Objective-C, добавив немного _Nullable. Но, насколько я понимаю, ваш код на Objective-C — это библиотека, которую вы не можете редактировать. Итак, вы должны иметь дело с этими String!, которые могут быть nil.

Но вы можете просто использовать технику 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")
}

С этим кодом Vendor он возвращает следующий результат:

@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
person Julien Quere    schedule 28.06.2016