特定条件下不会调用类扩展中的协议方法 [英] Protocol methods in a class extension are not called under specific conditions

查看:54
本文介绍了特定条件下不会调用类扩展中的协议方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个奇怪的行为.我能说的最好的方法是……当超类已经符合协议(通过扩展)时,不会调用类扩展中未覆盖的协议方法.但是,只有在使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆