【问题标题】:Can extension replace delegation in swift?扩展可以迅速取代委托吗?
【发布时间】:2016-09-07 05:43:13
【问题描述】:

我正在快速学习委托。本段使用示例来解释委托的工作原理。

在这个简单的例子中,我想确保我的应用的根视图 控制器,一个 UINavigationController,不允许应用旋转 — 当此视图时,应用程序应仅以纵向显示 控制器负责。但是 UINavigationController 不是我的课; 它属于可可。我自己的类是一个不同的视图控制器,一个 UIViewController 子类,充当 UINavigationController 的 孩子。孩子如何告诉父母如何旋转?出色地, UINavigationController 有一个委托属性,类型为 UINavigationControllerDelegate(一种协议)。它承诺发送这个 委托 navigationControllerSupportedInterfaceOrientations 需要知道如何旋转时的消息。

我的问题:我们可以扩展 myOwnViewController 以使用方法“navigationControllerSupportedInterfaceOrientations”来替换委托模式以实现相同的目标吗?

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    您可以扩展myOwnViewController,告诉扩展符合UINavigationControllerDelegate 协议并实现您想要的方法,但这并不能取代委托模式。如果您的扩展不符合此委托的协议,您将无法将myOwnViewController 附加为UINavigationController's 委托。

    class MyController: UIViewController {
    }
    
    extension MyController: UINavigationControllerDelegate {
        override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
            return .Portrait
        }
    }
    let navigationController = UINavigationController()
    let controller = MyController()
    navigationController.delegate = controller
    

    告诉MyController类符合UINavigationControllerDelegateprotocol可以达到同样的效果。

    class MyController: UIViewController, UINavigationControllerDelegate {
    
        override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
            return .Portrait
        }
    
    }
    let navigationController = UINavigationController()
    let controller = MyController()
    navigationController.delegate = controller
    

    这两个示例导致MyController 成为您的UINavigationController 的代表。这可能导致在一个地方承担许多责任。为了分担此责任,您可以创建另一个类作为导航控制器的委托。

    class MyController: UIViewController {}
    
    class NavigationDelegate: NSObject, UINavigationControllerDelegate {
    
        func navigationControllerSupportedInterfaceOrientations(navigationController: UINavigationController) -> UIInterfaceOrientationMask {
            return .Portrait
        }
    
    }
    let navigationController = UINavigationController()
    let controller = MyController()
    let navigationDelegate = NavigationDelegate()
    navigationController.delegate = navigationDelegate
    

    有什么区别?想象一下,你已经为你支持的方向方法实现了一个复杂的逻辑,你发现你不再使用MyController,而是使用DifferentController。由于您的方向逻辑位于MyController 中,因此无论如何您都需要创建它。但是,如果您的委托逻辑在 NavigationDelegate 类中分离,您可以使用 DifferentController 而无需仅为这些委托方法创建 MyController 类。

    【讨论】:

    • 你能比较一下这两种方式吗:使用扩展和段落中描述的原始方式?
    • 我已经通过比较更新了评论。我希望这会让它更清楚地理解。
    • 另一个问题:为什么UINavigationController 不包含 `navigationControllerSupportedInterfaceOrientations' 方法本身?同样的原因?为了灵活性?
    • 如果UINavigationController 有这个方法,那么你必须从UINavigationController 继承并覆盖它。这将使您的逻辑与这个特定的类紧密耦合。使用委托模式,您可以轻松地将其注入导航控制器。想象一下,您有两个导航控制器子类,它们在调用 viewDidLoad 时打印不同的内容,但共享相同的受支持方向逻辑。使用委托模式,您可以将 NavigationDelegate 类注入两个子类,而不是在两个地方使用相同的代码。
    • 我想举一个具体的例子。如果我们没有委托模式,我们可以简单地调用myVC. navigationControllerSupportedInterfaceOrientations == .Portrait 。在委托模式中,我们必须做更多的事情。所以我不清楚最后一条评论中的最后一句话。虽然我们在两个地方有相同的代码,但它看起来仍然更短更整洁。
    猜你喜欢
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    • 2015-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-03
    相关资源
    最近更新 更多