[英]How do I remove swift non-optional unwrapping with obj-c class instance?
[英]Prevent Obj-C code from passing `nil` to a Swift method with non-optional parameters
我正在處理一個問題,其中 Obj-C 代碼可以將nil
傳遞給不采用可選參數的 Swift 方法。
我正在為 Xcode 編譯器尋找一種方法來防止這種情況發生。 似乎所有的可空性注釋都是為了 Swift 調用 Objc,反之亦然。
一些示例代碼:
// file1.swift
@objc
class Foo: NSObject {
@objc let date: Date? // default to nil
...
}
// file2.swift
extension Date {
@objc(doSomethingWithOtherDate:)
func doSomething(with otherDate: Date) {
print(date)
}
}
然后在 Obj-c 中,我們調用 Swift 方法傳入一個可選值,其中nil
:
// file3.m
[Date.new doSomethingWithOtherDate:[Foo.new date]];
有沒有辦法防止這種情況? 我們如何告訴編譯器doSomethingWithOtherDate
不采用nil
。
跟進此問題,在調用中傳遞文字nil
會觸發警告,這非常有幫助。 但是,傳遞一個nil
值不會觸發任何事情。 但是,如果 nil 引用是本地的,static 分析器確實會發現問題。
但是,如果通過另一個 object 傳遞nil
引用,則 static 分析器無法識別此問題。
我做了這個 repo 來展示這個問題: https://github.com/eneko/ObjcCrashDemo
一般來說,沒有。 Objective-C 對可空性的了解不足,無法檢測到所有情況。
如果你顯式地傳遞 nil 你應該得到一個警告“Null passed to a callee that requires a non-null argument”。 您可以通過將-Werror=nonnull
添加到構建設置中的“其他警告標志”來將其轉化為錯誤。
然而,這是極其有限的。 甚至像NSDate* date = nil;
這樣簡單的東西並通過它不會產生警告/錯誤。 即使在nonnull
中添加一個非空屬性並傳遞它也不會產生警告/錯誤。
我能夠找到這篇文章: https://fabiancanas.com/blog/2020/1/9/swift-undefined-behavior.html (搜索“當 nil 不可能時檢測 nil”部分)。 本文討論了一個相當復雜的問題解決方案,但我建議更簡單的解決方案是將 function 參數類型聲明為Date!
(一個值或 nil)然后在繼續處理 function 主體之前對傳遞的值執行guard let
:
// file2.swift
extension Date {
@objc(doSomethingWithOtherDate:)
func doSomething(with otherDate: Date!) {
guard let od = otherDate else {
// do something else
return
}
print(date)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.