tipos programacion parametros parametro parameter opcional metodo functions funciones funcion externos con swift

programacion - swift functions parameters



Clase conforme al protocolo como parámetro de función en Swift (6)

¿Qué hay de esta manera ?:

protocol MyProtocol { func getTableViewDataSource() -> UITableViewDataSource func getViewController() -> UIViewController } class MyVC : UIViewController, UITableViewDataSource, MyProtocol { // ... func getTableViewDataSource() -> UITableViewDataSource { return self } func getViewController() -> UIViewController { return self } } func foo(_ vc:MyProtocol) { vc.getTableViewDataSource() // working with UITableViewDataSource stuff vc.getViewController() // working with UIViewController stuff }

En Objective-C, es posible especificar una clase que se ajuste a un protocolo como un parámetro de método. Por ejemplo, podría tener un método que solo permita un UIViewController que se ajuste a UITableViewDataSource :

- (void)foo:(UIViewController<UITableViewDataSource> *)vc;

No puedo encontrar una manera de hacer esto en Swift (quizás aún no sea posible). Puede especificar múltiples protocolos usando func foo(obj: protocol<P1, P2>) , pero ¿cómo requiere que el objeto sea también de una clase en particular?


Con Swift 3, puede hacer lo siguiente:

func foo(_ dataSource: UITableViewDataSource) { self.tableView.dataSource = dataSource } func foo(_ delegateAndDataSource: UITableViewDelegate & UITableViewDataSource) { //Whatever }


En Swift 4 puedes lograr esto con el nuevo & sign:

let vc: UIViewController & UITableViewDataSource


La documentación del libro Swift sugiere que use restricciones de tipo con una cláusula where:

func someFunction<C1: SomeClass where C1:SomeProtocol>(inParam: C1) {}

Esto garantiza que "inParam" es del tipo "SomeClass" con la condición de que también se adhiera a "SomeProtocol". Incluso tiene el poder de especificar múltiples cláusulas where delimitadas por una coma:

func itemsMatch<C1: SomeProtocol, C2: SomeProtocol where C1.ItemType == C2.ItemType, C1.ItemType: SomeOtherProtocol>(foo: C1, bar: C2) -> Bool { return true }


Puede definir foo como una función genérica y usar restricciones de tipo para requerir una clase y un protocolo.

Swift 4

func foo<T: UIViewController & UITableViewDataSource>(vc: T) { ..... }

Swift 3 (funciona también para Swift 4)

func foo<T: UIViewController>(vc:T) where T:UITableViewDataSource { .... }

Swift 2

func foo<T: UIViewController where T: UITableViewDataSource>(vc: T) { // access UIViewController property let view = vc.view // call UITableViewDataSource method let sections = vc.numberOfSectionsInTableView?(tableView) }


Nota en septiembre de 2015 : Esta fue una observación en los primeros días de Swift.

Parece ser imposible. Apple también tiene esta molestia en algunas de sus API. Aquí hay un ejemplo de una clase recientemente introducida en iOS 8 (a partir de beta 5):

UIInputViewController de textDocumentProxy :

Definido en Objective-C de la siguiente manera:

@property(nonatomic, readonly) NSObject<UITextDocumentProxy> *textDocumentProxy;

y en Swift:

var textDocumentProxy: NSObject! { get }

Enlace a la documentación de Apple: https://developer.apple.com/library/prerelease/iOS/documentation/UIKit/Reference/UIInputViewController_Class/index.html#//apple_ref/occ/instp/UIInputViewController/textDocumentProxy