shallowThought
shallowThought

Reputation: 19602

Method not found at runtime

I have the following extension in my personal toolbox library:

public extension UIViewController {

    public func removeChildViewControllers() {
        for child in self.childViewControllers {
            child.willMove(toParentViewController: nil)
            child.view.removeFromSuperview()
           child.removeFromParentViewController()
        }
   }

    public func addChildViewController(_ controller: UIViewController, embedViewIn containerView: UIView) {
        controller.willMove(toParentViewController: self)
        addChildViewController(controller)
        containerView.addSubview(controller.view)
        controller.view.addCustomConstraints(CustomConstrains.FullSizeInSuperview)
        controller.didMove(toParentViewController: self)
    }
}

From my current app, I call as follows:

private func embedViewController(_ controller: UIViewController) {
    removeChildViewControllers()    
    addChildViewController(controller, embedViewIn: containerView)
}

Everything is working as expected.

Now I add one more convenience Method removeChildViewController:

public extension UIViewController {

    public func removeChildViewControllers() {
        for child in self.childViewControllers {
            child.willMove(toParentViewController: nil)
            child.view.removeFromSuperview()
           child.removeFromParentViewController()
        }
   }

    public func addChildViewController(_ controller: UIViewController, embedViewIn containerView: UIView) {
        controller.willMove(toParentViewController: self)
        addChildViewController(controller)
        containerView.addSubview(controller.view)
        controller.view.addCustomConstraints(CustomConstrains.FullSizeInSuperview)
        controller.didMove(toParentViewController: self)
    }

    public func removeChildViewController(_ controller: UIViewController) {
        controller.willMove(toParentViewController: nil)
        controller.view.removeFromSuperview()
        controller.removeFromParentViewController()
    }
}

From now on, calling the code which has not been modified crashes at runtime EXC_BAD_ACCESS:

removeChildViewControllers()

To sum it up:

Calling removeChildViewControllers() crashes on runtime if the (unused) method removeChildViewController exists.

Calling removeChildViewControllers() does not crash on runtime if the (unused) method removeChildViewController is commented.

Also, calling removeChildViewControllers() does not crash on runtime if the (unused) method removeChildViewController is renamed to removeChildViewControllerr.

Upvotes: 3

Views: 126

Answers (1)

matt
matt

Reputation: 535304

I'm going to guess that this is one of those situations where you are banging into a secret namespace conflict. There probably is a removeChildViewController method hidden in the Objective-C Cocoa world, and you have stumbled over it by duplicating its name. Thus, Objective-C Cocoa chokes at runtime, even though the official API has no problem with it and so there is no trouble getting Swift to compile your code. This sort of thing happens all the time, unfortunately.

Upvotes: 3

Related Questions