[英]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.