Objective-C含可选参数的方法为何无法在Swift中仅传首参数调用?
为什么Swift中无法直接简化调用带nullable参数的Objective-C方法?
你的Objective-C方法:
-(void) runInWindow:(NSWindow*)parentWindow answerValidation:(nullable BOOL(^)(void))validator completion:(nullable void(^)(NSModalResponse returnCode))handler;
在Swift中会被自动桥接为:
func run(in parentWindow: NSWindow!, answerValidation validator: (() -> Bool)?, completion handler: ((NSModalResponse) -> Void)?)
Xcode不提示dlog.run(in:self.windowForSheet!)这种仅传第一个参数的调用形式,原因很明确:
- Objective-C的
nullable只是标记参数可以传nil,但并没有给参数设置默认值。Swift中要省略后续参数,必须这些参数有明确的默认值(比如= nil)。 - 自动桥接后的Swift方法里,后两个block参数只是可选类型(带
?),但没有默认值,所以调用时必须显式传入参数,哪怕是nil,比如:dlog.run(in: self.windowForSheet!, answerValidation: nil, completion: nil)
如果想要实现你期望的简化调用,有两种靠谱方案:
修改Objective-C方法,添加默认值
在Objective-C方法声明里给后两个nullable参数指定默认值NULL,这样Swift桥接时会自动带上默认值,就能直接省略后续参数调用:-(void) runInWindow:(NSWindow*)parentWindow answerValidation:(nullable BOOL(^)(void))validator = NULL completion:(nullable void(^)(NSModalResponse returnCode))handler = NULL;用Swift扩展封装简化接口
给dlog对应的Swift类写一个扩展,新增只接收第一个参数的重载方法,把后两个block默认设为nil:extension YourDLogClassName { func run(in parentWindow: NSWindow!) { self.run(in: parentWindow, answerValidation: nil, completion: nil) } }替换
YourDLogClassName为实际的类名后,就能直接用dlog.run(in:self.windowForSheet!)调用,Xcode也会提示这个简化形式。
内容的提问来源于stack exchange,提问作者Steve Mills
相关产品推荐
相关产品推荐

