2016-04-19 3 views
3

Предположим, что у меня есть протокол и класс, соответствующий этому протоколу.Дополнительные блокировки в протоколах Swift

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

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

Успешное закрытие является необязательным, поскольку не каждый звонок потребует его. Например, это обычная ситуация при вызове такой функции из модульного теста, потому что мы хотим выполнить ожидание в закрытии успеха, в то время как при обычном закрытии вызова по какой-либо причине не требуется.

Поскольку функция, определенная в протоколах не может иметь значений по умолчанию для своих параметров, для каждого вызова к задаче на объекте, соответствующий Foo, мы должны вызвать его с закрытием или передать явно ноль в качестве значения закрытия:

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

Что такое рекомендуемый метод для реализации такой структуры? Нужно ли нам каждый раз пропускать пустое замыкание или вызывать функции с значением закрытия, установленным в nil, или есть другой способ справиться с этим?

+0

Почему это уродливое? Существует множество случаев, когда вы можете передать нуль в блок завершения методов Apple. Например, 'vc.navigationController.pushViewController (vc2, animated: true, completion: noil)' Просто просто означает, что вы не хотите ничего делать после завершения задачи. – NSGangster

+0

. Я голосую, чтобы закрыть этот вопрос в качестве первичного мнения. Основано на том, что ответы могут основываться только на личном мнении, а не на факте. 'Какой рекомендуемый метод для реализации такой структуры? Для меня каждый раз пустые замыкания или вызывающие функции с значением замыкания, установленным на nil, являются довольно уродливыми. «Что уродливо для вас или кого-то другого рекомендует, это не факт. – JAL

+0

@JAL мое мнение здесь не имеет значения, я хотел спросить, есть ли лучший способ реализовать такую ​​структуру. Я отредактирую вопрос и удалю это предложение – pkacprzak

ответ

0

Вот пример того, как вы можете реализовать. = Nil может не понадобиться, но я не тестировал.

func doSomething(closure:(()->Void)? = nil) { 
    closure?() 
} 
+0

Когда объект имеет тип Foo, который является протоколом, он не знает, что функция в конкретной реализации имеет параметр по умолчанию set – pkacprzak

+0

, возможно, это не нужно знать. –

0

Моя рекомендация:

Вместо этого:

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

Используйте это:

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

Вы всегда можете пройти пустое замыкание, если вам не нужно обрабатывать завершение задачи. Опциональные блокировки просто делают ваш код более понятным.

Смежные вопросы