2016-06-28 16 views
6

Tôi đang có một lớp mô hình như sau, trong thư viện được viết trong Objective-C. Tôi đang tiêu thụ lớp này trong dự án nhanh chóng của tôi. Trong nhanh chóng nó trở thành tài sản của loại String!. Đôi khi tài sản đó sẽ là số không. Vì vậy, tôi đang thử nghiệm xác nhận con số không như sau:Swift - Kiểm tra nil của biến tùy chọn chưa được nén

Vendor.h

@interface Vendor: NSObject { 

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

Trong dự án Swift của tôi, tôi đang kiểm tra xác nhận con số không cho các tài sản Middlename như sau:

if anObject.middleNam != nil { // Here, It throws runtime error: fatal error: Unexpectedly found nil while unwrapping an Optional value 
} 

Nó ném cho tôi một lỗi thời gian chạy sau:

fatal error: unexpectedly found nil while unwrapping an Optional value 

Nếu thuộc tính mục tiêu C tiếp xúc trong s wift as String? sau đó tôi đã sử dụng như sau:

if let middleName = anObject.middleName { 

} 

Làm cách nào để kiểm tra biến tùy chọn chưa được mở.

Xin cảm ơn trước.

+0

Bạn có thể sử dụng 'if let' với các tùy chọn hoàn toàn chưa được mở - mặc dù kiểm tra'! = nil' sẽ hoạt động erly với 'middleName',' anObject' được định nghĩa như thế nào? – Hamish

Trả lời

5

Nếu bạn muốn sở hữu ObjectiveC được tiếp xúc trong Swift như tùy chọn, đánh dấu nó với _Nullable thẻ như

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

Bây giờ tên Middlename sẽ là tùy chọn kiểu String? thay vì String! và bạn có điều kiện có thể Unwrap nó .

Đọc về nhiều Nullability in ObjC

+0

Lưu ý rằng tài sản của OP đã được hiển thị trong Swift như một tùy chọn (nó chỉ ẩn hoàn toàn) và anh ta có thể sử dụng unwrapping có điều kiện trên nó. Trong Swift 3, một tùy chọn không được khai báo hoàn toàn là kiểu chính xác giống như một tùy chọn thông thường - nó chỉ có một thuộc tính cho trình biên dịch biết rằng nó có tùy chọn để buộc unwrap nó trong các tình huống nhất định. Và những tình huống này không bao gồm kiểm tra 'nil' hoặc unwrapping có điều kiện. Mã của OP đang làm việc tốt cho tôi - tôi nghi ngờ vấn đề của anh ta là 'anObject' được định nghĩa là IUO và đó là những gì đang nhận được lực lượng chưa được khai thác. – Hamish

+0

Mặc dù tôi chắc chắn đồng ý rằng việc thêm các thẻ vô hiệu vào các loại obj-c là một cách tốt để đi, đặc biệt là khi giao tiếp với Swift. – Hamish

+0

@ originaluser2 Tôi đồng ý với quan điểm của bạn.nó sẽ được ẩn hoàn toàn tùy chọn, và anh ta vẫn có thể sử dụng unwrapping có điều kiện trên nó nhưng trình biên dịch sẽ không phàn nàn nếu bạn không làm và điều này sẽ gây ra sự cố trong các tình huống như '' let middleName: String = object.middleName'. Vì vậy, nó là một thực hành tốt để đánh dấu bằng thẻ nullable, do đó ai sẽ sử dụng nó sẽ nhận được cảnh báo trình biên dịch và anh ta có thể xử lý nó một cách an toàn. –

2

Như Anil đã đề cập, giải pháp tốt nhất là nên chỉnh sửa mã Objective-C của bạn để thêm một số _Nullable. Nhưng, như tôi hiểu, mã Mục tiêu-C của bạn là một thư viện mà bạn không thể chỉnh sửa. Vì vậy, bạn phải xử lý các số này String! có thể là nil.

Nhưng bạn chỉ có thể sử dụng if let kỹ thuật như thế này:

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") 
} 

Với Vendor mã này, nó sẽ trả về kết quả sau:

@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 

Kết quả:

Here is my firstName: Julien 
I have no middleName 
Here is my name: Quere 
Các vấn đề liên quan