Ios 子类中的Swift 3 API重命名

Ios 子类中的Swift 3 API重命名,ios,swift,methods,uicollectionview,subclass,Ios,Swift,Methods,Uicollectionview,Subclass,我在代码中遇到了一些意外的行为,其中UICollectionViewDelegate回调仅在我使用前Swift 3方法签名时才会收到 为了演示此问题,我创建了两个视图控制器子类: class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource { @IBOutlet var collectionView: UICollectionView! func co

我在代码中遇到了一些意外的行为,其中
UICollectionViewDelegate
回调仅在我使用前Swift 3方法签名时才会收到

为了演示此问题,我创建了两个视图控制器子类:

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(\uu:willDisplay:forItemAt:)
方法

首先要注意的是,如果我将该方法的旧变体(
collectionView(\ux0:willDisplayCell:forItemAtIndexPath:)
)添加到
ViewController
,编译器会很有帮助地警告我该方法已被重命名:

'collectionView(_:willDisplayCell:forItemAtIndexPath:)' has been renamed to 'collectionView(_:willDisplay:forItemAt:)'
但是,将相同的方法添加到
SubViewController
不会产生任何警告–它似乎会像对待任何其他以前未定义的方法一样对待它

如果我使用
ViewController
的实例运行应用程序(取消对
collectionView(\uz:willDisplay:at:)
方法的注释,并在
SubViewController
中对其进行注释),则会调用正确的委托方法(使用新方法名称)。如果改用类
SubViewController
,将调用错误的委托方法(使用旧方法名)


这是正确的行为吗?若然,原因为何?这使得我很难推断应该使用哪种方法签名,特别是当在
SubViewController

中实际调用的方法似乎没有编译时检查时,正如其中一条注释中所指出的,此问题的解决方案是在函数前面添加
@objc

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

复制您的示例时,SubViewController方法出现错误
collectionView(u1;:willDisplay:forItemAt:)
有错误
重写声明需要一个“override”关键字
collectionView(\uU:willDisplayCell:forItemAtIndexPath:)
有错误
Method'collectionView(\uU:willDisplayCell:forItemAtIndexPath:)'与Objective-C选择器的'collectionView:willDisplayCell:ForItemAtExPath:'方法冲突。
。Xcode 8.0。@MikeTaverne抱歉,是的,您需要注释掉当前未测试的类中的方法。我在对问题的一次编辑中更清楚地说明了这一点。在子类中具有新名称的方法上方添加
@objc(collectionView:willDisplayCell:forItemAtIndexPath:)
(并删除具有旧名称的方法)会调用具有新名称的方法。我只是想添加一点我发现的信息,所以显然Swift 3方法名称转换规则在运行时不适用。这应该是一个错误。谢谢你填写错误报告。还有另一个问题,关于协议和扩展中可能实际相关的Swift方法重命名。