Элегантный способ пропускать пустые закрытия в Swift
В Swift мне часто приходится пропускать замыкание на ноль для метода, чтобы соответствовать методу ожидаемых параметров (arity). В старые добрые времена Obj C можно было пройти nil
для обратного вызова noop и сделать с ним. Есть ли более быстрый и элегантный способ сделать это в Swift без прохождения пустого блока, как показано ниже?
UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: { (UIAlertAction) -> Void in }) // do nothing in callback
Полный пример:
import UIKit
class UIAlertControllerFactory {
class func ok(title: String, message: String) -> UIAlertController {
var alertController = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
var okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: { (UIAlertAction) -> Void in
})
alertController.addAction(okAction)
return alertController
}
}
Ответы
Ответ 1
Общий способ, если вы не можете пройти nil
:
var okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default,
handler:{ _ in })
Вы также можете передать nil
в этом случае, потому что (с iOS 9.0) обработчик является Optional
:
var okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default,
handler:nil)
Ответ 2
Согласно документации Xcode, UIAlertAction
имеет метод convenience init
со следующим объявлением:
convenience init(title: String, style: UIAlertActionStyle, handler: ((UIAlertAction!) -> Void)!)
Как вы можете видеть, параметр handler
является Неявно Unwrapped Необязательный типа ((UIAlertAction!) -> Void)!
. Поэтому вы можете передать nil
для этого. Например, вы можете создать экземпляр UIAlertController
, содержащий один UIAlertAction
с handler: nil
:
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
alertController.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
presentViewController(alertController, animated: true, completion: nil)
Поэтому вам не нужно создавать пустой блок для handler
.
Ответ 3
Вы можете определить noop, который будет использоваться как закрытие по умолчанию, которое ничего не делает: (Ссылка: https://realm.io/news/closures-api-design)
func noop() {}
func noop<T>(value: T) {}
func noop<T>() -> T? { return nil }
func noop<T, S>(value: T) -> S? { return nil }
Для использования:
var okAction = UIAlertAction(title: "Ok",
style: UIAlertActionStyle.Default,
handler: noop)
Ответ 4
extension UIAlertAction {
convenience init(title: String, style: UIAlertActionStyle) {
return self.init(title: title, style: style, handler: { (UIAlertAction) -> Void in })
}
}
и просто оставьте последний аргумент. Вы можете поместить это в свой "factory".