簡體   English   中英

防止 Obj-C 代碼將“nil”傳遞給帶有非可選參數的 Swift 方法

[英]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 分析器無法識別此問題。

Objc - Swift 崩潰

我做了這個 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM