Swift 3 API cambio de nombre en subclasss

He encontrado algún comportamiento inesperado en mi código donde UICollectionViewDelegate devoluciones de llamada de UICollectionViewDelegate solo se reciben si utilizo las firmas del método anterior a Swift 3.

Para demostrar este problema, he creado dos subclasss de controller de vista:

 class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource { @IBOutlet var collectionView: UICollectionView! func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 100 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { return collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) } // func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { // print(#function) // } } class SubViewController: ViewController { func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { print(#function) } func collectionView(_ collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: IndexPath) { print(#function) } } 

La callback de interés es el método collectionView(_:willDisplay:forItemAt:) .

Lo primero a tener en count es que si agrego la variante anterior de ese método ( collectionView(_:willDisplayCell:forItemAtIndexPath:) ) a ViewController , el comstackdor me advierte amablemente que se ha cambiado el nombre del método:

 'collectionView(_:willDisplayCell:forItemAtIndexPath:)' has been renamed to 'collectionView(_:willDisplay:forItemAt:)' 

Sin embargo, agregar el mismo método a SubViewController no produce ninguna advertencia; parece tratarlo como lo haría con cualquier otro método previamente indefinido.

Si ejecuto la aplicación con una instancia de ViewController (descomenta el método collectionView(_:willDisplay:at:) allí, y SubViewController en SubViewController ), se SubViewController el método de delegado correcto (con el nuevo nombre de método). Si en su lugar uso la class SubViewController , se SubViewController el método de delegado incorrecto (con el nombre del método anterior).

¿Es este el comportamiento correcto? Si es así, ¿por qué? Hace que sea un tanto difícil de razonar sobre qué firmas de método debo usar, especialmente cuando parece que no hay ninguna comprobación de time de compilation del método que realmente se llama en SubViewController .

Como se señaló en uno de los comentarios, la solución a este problema es agregar @objc delante de la function como esta.

 @objc (collectionView:willDisplayCell:forItemAtIndexPath:) func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { // code goes here }