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方法重命名。