Em Objective-C, é possível especificar uma classe em conformidade com um protocolo como parâmetro de método. Por exemplo, eu poderia ter um método que permite apenas um UIViewController
que esteja em conformidade com UITableViewDataSource
:
- (void)foo:(UIViewController<UITableViewDataSource> *)vc;
Não consigo encontrar uma maneira de fazer isso no Swift (talvez ainda não seja possível). Você pode especificar vários protocolos usando func foo(obj: protocol<P1, P2>)
, mas como você exige que o objeto também seja de uma determinada classe?
Respostas:
Você pode definir
foo
como uma função genérica e usar restrições de tipo para exigir uma classe e um protocolo.Swift 4
Swift 3 (funciona também para Swift 4)
Swift 2
fonte
protocol<>
fornece (masprotocol<>
não pode conter tipos que não sejam de protocolo).numberOfSectionsInTableView
porque é uma função necessária noUITableViewDataSource
?numberOfSectionsInTableView:
é opcional - você pode estar pensandotableView:numberOfRowsInSection:
.func foo<T: UIViewController>(vc:T) where T:UITableViewDataSource { ... }
No Swift 4, você pode conseguir isso com o novo & sinal:
fonte
A documentação do livro Swift sugere que você use restrições de tipo com uma cláusula where:
Isso garante que "inParam" seja do tipo "SomeClass" com a condição de que também adere a "SomeProtocol". Você ainda tem o poder de especificar várias cláusulas where delimitadas por uma vírgula:
fonte
Com o Swift 3, você pode fazer o seguinte:
fonte
E desta forma ?:
fonte
Swift 5:
Então, essencialmente , a resposta de Jeroen acima.
fonte
Nota em setembro de 2015 : Esta foi uma observação nos primeiros dias do Swift.
Parece impossível. A Apple também tem esse aborrecimento em algumas de suas APIs. Aqui está um exemplo de uma classe recém-introduzida no iOS 8 (a partir do beta 5):
UIInputViewController
'stextDocumentProxy
propriedade:Definido em Objective-C da seguinte forma:
e em Swift:
Link para a documentação da Apple: https://developer.apple.com/library/prerelease/iOS/documentation/UIKit/Reference/UIInputViewController_Class/index.html#//apple_ref/occ/instp/UIInputViewController/textDocumentProxy
fonte
var textDocumentProxy: UITextDocumentProxy! { get }
@protocol MyAwesomeCallbacks <NSObject>