Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 从超类中识别子类_Ios_Swift_Oop_Inheritance - Fatal编程技术网

Ios 从超类中识别子类

Ios 从超类中识别子类,ios,swift,oop,inheritance,Ios,Swift,Oop,Inheritance,我有一个BaseViewController,从中我的SearchViewController是子类。我需要将超类中按钮的目标分配给子类中的方法。我在超类中有一个名为addBackButton(:)的方法,它在navigationView(定制视图)中添加了一个按钮。我从子类调用这个方法 func addBackButton() { let button = UIButton(type: .custom) button.frame = CGRect(x: 10,

我有一个
BaseViewController
,从中我的
SearchViewController
是子类。我需要将超类中按钮的目标分配给子类中的方法。我在超类中有一个名为
addBackButton(:)
的方法,它在navigationView(定制视图)中添加了一个按钮。我从子类调用这个方法

 func addBackButton() {
        let button = UIButton(type: .custom)
        button.frame = CGRect(x: 10, y: 20, width: 44, height: 44)
        button.setImage(UIImage(named: "back")?.withRenderingMode(.alwaysTemplate), for: UIControlState())
        button.tintColor = currentTheme.navButtonTintColor
        switch self {
        case is SearchViewController:
            let controller: SearchViewController = self as! SearchViewController
            button.addTarget(controller, action: #selector(controller.backButtonTapped(_:)), for: .touchUpInside)
            break
        case is HelpViewController:
            let controller: HelpViewController = self as! HelpViewController
            button.addTarget(controller, action: #selector(controller.backButtonTapped(_:)), for: .touchUpInside)
            break
        default:
            break
        }

        navigationBarView.addSubview(button)
    }
我所做的(代码在swif 3中): 上面的方法接受一个viewcontroller对象,我通过将
self
传递给该方法,从子类调用它,这样它就可以正常工作了。方法定义如下:

 func addBackButton(from vc: AnyObject) {
        let button = UIButton(type: .custom)
        button.frame = CGRect(x: 10, y: 20, width: 44, height: 44)
        button.setImage(UIImage(named: "back")?.withRenderingMode(.alwaysTemplate), for: UIControlState())
        button.tintColor = currentTheme.navButtonTintColor
        if vc.isKind(of:SearchViewController.self) {
            let controller: SearchViewController = self as! SearchViewController
            button.addTarget(controller, action: #selector(controller.backButtonTapped(_:)), for: .touchUpInside)

        }
        navigationBarView.addSubview(button)
    }
我有两个问题:

  • 超类与子类之间的正确通信方式是什么
  • 上述方法效果良好。但是如果我做了
    'vc是SearchViewController'
    'vc.isKind(of:SearchViewController.self)
    ,这两种方法都可以正常工作。从超类中识别子类的正确方法是什么
  • 编辑: 根据anbu.karthiks的评论,我使用了超类中的self来标识子类

     func addBackButton() {
            let button = UIButton(type: .custom)
            button.frame = CGRect(x: 10, y: 20, width: 44, height: 44)
            button.setImage(UIImage(named: "back")?.withRenderingMode(.alwaysTemplate), for: UIControlState())
            button.tintColor = currentTheme.navButtonTintColor
            switch self {
            case is SearchViewController:
                let controller: SearchViewController = self as! SearchViewController
                button.addTarget(controller, action: #selector(controller.backButtonTapped(_:)), for: .touchUpInside)
                break
            case is HelpViewController:
                let controller: HelpViewController = self as! HelpViewController
                button.addTarget(controller, action: #selector(controller.backButtonTapped(_:)), for: .touchUpInside)
                break
            default:
                break
            }
    
            navigationBarView.addSubview(button)
        }
    

    是的,你做这件事的方法很好,而且是一种方法。另一种方法是:

    if let controller = vc as? SearchViewController {
        // use controller in here which is casted to your class and ready to be used
    }
    
    因此,您的代码:

    func addBackButton(from vc: AnyObject) {
        let button = UIButton(type: .custom)
        button.frame = CGRect(x: 10, y: 20, width: 44, height: 44)
        button.setImage(UIImage(named: "back")?.withRenderingMode(.alwaysTemplate), for: UIControlState())
        button.tintColor = currentTheme.navButtonTintColor
        if let controller = vc as? SearchViewController {
            button.addTarget(controller, action: #selector(controller.backButtonTapped(_:)), for: .touchUpInside)
        }
        navigationBarView.addSubview(button)
    }
    
    超类与子类之间的正确通信方式是什么


    没有什么是对的或错的,但是有些方法比其他的好。查看我上面的示例,了解如何执行此操作。

    这不是子类和超类之间通信的正确方法, 事实上,这种方法是反面向对象的

    在位于超类中的
    addBackButton()
    函数中执行向下转换与面向对象的思想相冲突

    在超类中,您应该放置与所有子类兼容的通用代码,如果您需要向特定类添加一些额外的代码,您应该重写该函数,并将指定代码写入特定子类,并在需要时调用super.“functionName”

    在代码中,可以在名为backbuttoncapped()的超类中创建一个函数 并在任何子类中重写此函数,并编写所需的特定代码

    像这个例子:

    class SuperClass: UIViewController {
    
        let navigationBarView = UINavigationBar()
    
        func addBackButton(from vc: AnyObject) {
            let button = UIButton(type: .custom)
            button.frame = CGRect(x: 10, y: 20, width: 44, height: 44)
            button.setImage(UIImage(named: "back")?.withRenderingMode(.alwaysTemplate), for: UIControlState())
            button.tintColor = .white
            button.addTarget(self, action: #selector(backButtonTapped), for: .touchUpInside)
            navigationBarView.addSubview(button)
        }
    
        @objc func backButtonTapped() {
            //every subClass will override this funcion and handle it
        }
    }
    
    class Subclass: SuperClass {
    
        override func backButtonTapped() {
            //Do your specific code....
        }
    }
    

    我希望这是有帮助的。

    是的,正确…,简单的自我识别子类很好谢谢@Anbu.Karthik。我的想法很复杂。我删除了函数参数,只是在超类中使用了一个开关
    self
    ,工作正常。谢谢@Rashwan。你能像我一样使用
    is
    关键字来识别超类吗?我已经编辑了这个问题。请看一看。