繁体   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