2016-10-05 14 views
3

私のコードで予期しない動作が発生しました。コールバックは、Pre-Swift 3メソッドシグニチャを使用する場合にのみ受信されます。この問題を実証するためにSwift 3 APIのサブクラスでの名前変更

、私は2つのビューコントローラのサブクラスを作成している:関心のコールバックがcollectionView(_:willDisplay:forItemAt:)方法である

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) 
    } 
} 

を。

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

は、しかし、同じメソッドを追加:

注意すべき最初の事は、私はViewControllerにそのメソッド(collectionView(_:willDisplayCell:forItemAtIndexPath:))の古いバリアントを追加した場合、コンパイラは親切メソッドの名前が変更されたことを私に警告していることですSubViewControllerには警告が生成されません。以前に定義されていなかった他の方法と同様に扱われるようです。

私は(そこcollectionView(_:willDisplay:at:)メソッドのコメントを解除し、SubViewControllerでそれをコメントアウト)ViewControllerのインスタンスにアプリケーションを実行する場合、(新しいメソッド名で)正しいデリゲートメソッドが呼び出されます。代わりにクラスSubViewControllerを使用すると、(古いメソッド名の)間違ったデリゲートメソッドが呼び出されます。

これは正しい動作ですか?もしそうなら、なぜですか?実際にSubViewControllerというメソッドがコンパイル時にチェックされていないような場合には、どのメソッドシグネチャを使用すべきかを判断するのがやや難しくなります。

+0

例をコピーすると、SubViewControllerメソッドでエラーが発生します。 'collectionView(_:willDisplay:forItemAt:)'にエラーがあります。オーバーライド宣言には 'override'キーワードが必要です。 Objective-Cセレクタで 'collectionView(_:willDisplayCell:forItemAtIndexPath:) 'エラーが発生しました' method 'collectionView(_:willDisplayCell:forItemAtIndexPath :)コレクションビュー:willDisplayCell:forItemAtIndexPath:'メソッドとの競合 'collectionView(_:willDisplay:forItemAt :)を同じObjective-Cセレクタで実行します。 Xcode 8.0。 –

+0

@MikeTaverne申し訳ありません。現在テストされていないクラスのメソッドをコメントアウトする必要があります。私は質問の編集でそれをより明確にしました。 – Stuart

+3

サブクラスに新しい名前を持つメソッドの上に '@objc(collectionView:willDisplayCell:forItemAtIndexPath:)'を追加して(古い名前のメソッドを削除する)、新しい名前のメソッドが呼び出されます。ちょうど私が見つけたビット情報を追加したい。 –

答えて

1

コメントの1つに指摘したように、この問題の解決策は、@objcをこのような関数の前に追加することです。

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