Swift协议中的可选闭包

3
假设我有一个协议和一个符合该协议的类。
protocol Foo {
    func task(success: (() -> Void)?)
}

class Bar: Foo {
    func task(success: (() -> Void)?) {
        //DO STUFF
    }
}

成功闭包是可选的,因为并非每次调用都需要它。例如,在从单元测试中调用此类函数时,这是一种常见情况,因为我们想在成功闭包中实现期望,而在常规调用中,某些原因不需要成功闭包。

由于在协议中定义的函数不能具有其参数的默认值,因此对于符合 Foo 的对象上的任务的每次调用,我们必须使用闭包调用它或将 nil 显式传递为闭包值:

var obj: Foo
obj = Bar()
obj.task(nil) //CLOSURE VALUE SET TO nil
obj.task() {} //EMPTY CLOSURE
obj.task() //NOT ALLOWED

什么是推荐的实现此类结构的方法?我们需要每次传递空闭包,还是调用闭包值设置为nil的函数,或者还有其他处理方式?

为什么这样丑陋?有很多情况下,您可能会将nil传递到苹果方法的完成块中,例如vc.navigationController.pushViewController(vc2, animated: true, completion:nil)。这只是意味着在任务完成后您不想做任何事情。 - NSGangster
我投票关闭这个问题,因为答案只能基于个人观点而非事实。对于如何实现这样的结构,推荐的方法是什么?对我来说,每次传递空闭包或将闭包值设置为nil调用函数有点丑陋。但是,你认为什么丑陋或别人推荐什么并不是事实。 - JAL
@JAL 我的意见在这里并不重要,我想问一下是否有更好的方法来实现这样的结构。我会编辑问题并删除这句话。 - pkacprzak
定义“更好”。你的问题仍然是主观的。 - JAL
@JAL 这个问题已经被编辑过了,现在没有个人意见。 - pkacprzak
显示剩余2条评论
2个回答

1
我的建议:
不要使用这个:
protocol Foo {
    func task(success: (() -> Void)?)
}

使用这个:

protocol Foo {
    func task(success: () -> Void)
}

如果您不需要处理任务完成,可以始终传递空闭包。可选闭包只会使您的代码意图不够清晰。


0
这是一个实现的例子。"= nil"可能不是必要的,但我还没有测试过。
func doSomething(closure:(()->Void)? = nil) {
     closure?()
}

当对象的类型为Foo,即一个协议时,它并不知道特定实现中的函数是否设置了默认参数。 - pkacprzak
也许它不需要知道。 - Nicolas Manzini

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接