特定条件下不会调用类扩展中的协议方法 [英] Protocol methods in a class extension are not called under specific conditions
问题描述
我遇到了一个奇怪的行为.我能说的最好的方法是……当超类已经符合协议(通过扩展)时,不会调用类扩展中未覆盖的协议方法.但是,只有在使用 release
构建配置构建时才会发生这种情况.
A 类:UIViewController {}扩展 A: UIScrollViewDelegate {func scrollViewDidScroll(_ scrollView: UIScrollView) {打印(超类中的scrollViewDidScroll")}}B类:A{//这里设置了一个 tableView(及其数据源和委托)...}扩展 B: UITableViewDelegate {覆盖 func scrollViewDidScroll(_ scrollView: UIScrollView) {super.scrollViewDidScroll(scrollView)print("子类中的scrollViewDidScroll")}func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {打印(scrollViewDidEndDragging")}}
<块引用>
输出:
超类中的scrollViewDidScroll
子类中的scrollViewDidScroll
scrollViewDidEndDragging
但是,如果我使用 release
构建配置构建它,输出是
超类中的scrollViewDidScroll
子类中的scrollViewDidScroll
如果我不在类B
中使用协议一致性方法的扩展,而是使用常规方式代替我可以解决问题(将实现协议的方法放入班级).
问题是……怎么会?
我也遇到了同样的问题.
Xcode 版本 - 12.4Swift 版本 - 4.2
我还遇到只有在应用程序中调用 applicationDidBecomeActive 方法时才会显示此行为.(主要是当您导航到其他屏幕(如身份验证等)时)
修复:您需要再次将 ViewController 指定为委托.
func applicationDidBecomeActive(_ application: UIApplication) {fixForCallBackInExt()}func fixForCallBackInExt() {守卫让 navController = window?.rootViewController as?UINavigationController else { return }如果让 tabVC = navController.topViewController 作为?UITabBarController, let topVC = tabVC.selectedViewController, topVC.isKind(of: UIViewController.self) {//设置你的委托 = topVC} else if let topVC = navController.topViewController, topVC.isKind(of: UIViewController.self) {//设置你的委托 = topVC}}
I encountered a weird behavior. The best way I can put it is … Not overridden protocol methods in a class extension are not called while the superclass already conforms to the protocol (via extension). However this happens only while it's build with the release
build configuration.
class A: UIViewController {}
extension A: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
print("scrollViewDidScroll in superclass")
}
}
class B: A {
// A tableView (and its data source and delegate) is set here…
}
extension B: UITableViewDelegate {
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
super.scrollViewDidScroll(scrollView)
print("scrollViewDidScroll in subclass")
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
print("scrollViewDidEndDragging")
}
}
The output:
scrollViewDidScroll in superclass
scrollViewDidScroll in subclass
scrollViewDidEndDragging
however if I build it with the release
build configuration, the output is
scrollViewDidScroll in superclass
scrollViewDidScroll in subclass
I can solve the problem if I don't use the extension for protocol conformance approach in the class B
and just use the regular way instead (put the methods that implement a protocol into the class).
The question is … how come?
I too encountered the same behaviour.
Xcode version - 12.4 Swift version - 4.2
I also encounter that this behaviour is shown only when applicationDidBecomeActive method is called in the application.(Mostly when you have navigation to some other Screen like authentication etc)
Fix: You need to assign the ViewController as delegate again.
func applicationDidBecomeActive(_ application: UIApplication) {
fixesForCallBackInExt()
}
func fixesForCallBackInExt() {
guard let navController = window?.rootViewController as? UINavigationController else { return }
if let tabVC = navController.topViewController as? UITabBarController, let topVC = tabVC.selectedViewController, topVC.isKind(of: UIViewController.self) {
// Set Your Delegate = topVC
} else if let topVC = navController.topViewController, topVC.isKind(of: UIViewController.self) {
// Set Your Delegate = topVC
}
}
这篇关于特定条件下不会调用类扩展中的协议方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!