菜鸟教程小白 发表于 2022-12-13 05:22:19

ios - 扩展 UIViewController 以访问应用程序委托(delegate)是一种反模式吗?


                                            <p><p>我使用的 API 建议将其客户端保留在应用委托(delegate)中并通过那里访问它。如果我扩展了 <code>UIViewController</code> 以更轻松地访问应用程序委托(delegate),这是否是一种反模式?</p>

<pre><code>extension UIViewController {
    var appDelegate: AppDelegate {
      return UIApplication.shared.delegate as! AppDelegate
    }
}

class SomeViewController: UIViewController {
    ...
    appDelegate.someClient.someMethod()
    ...
}
</code></pre>

<p>通过反模式,我的意思是为了这个简单的方便而扩展整个 <code>UIViewController</code> 类是不是有点过头了?总体而言,像这样扩展类(class)有什么负面影响吗?是否每个 ViewController ,即使它不访问 API,现在都隐式指向应用委托(delegate)?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><blockquote>
<p>If I extended UIViewController to make it easier to access the app
delegate, is this any way an antipattern?</p>

<pre><code>extension UIViewController {
    var appDelegate: AppDelegate {
      return UIApplication.shared.delegate as! AppDelegate
    }
}
</code></pre>
</blockquote>

<p>没有;恰恰相反。需要访问应用程序委托(delegate)并将其转换为其实际类以便能够访问应用程序委托(delegate)中的属性或调用方法是很常见的。如果这可能需要在多个地方完成,计算属性是提供速记的标准符号。 (没有必要为此使用扩展名,但这样做并没有什么坏处,并且可能有符号优势;例如,扩展名可以位于应用程序委托(delegate)文件中。)</p>

<hr/>

<p>在评论中,您会思考扩展 UIViewController 的智慧。我想您有两个 ViewController 需要访问应用程序委托(delegate),而其他许多则不需要。</p>

<p>现在,首先,这并没有真正改变我的答案。我看不出它会造成什么危害,或者它是如何以任何方式让所有 ViewController 能够通过快捷方式访问应用程序委托(delegate)的反模式,即使它们中的许多人实际上从未这样做过。所有的 ViewController 都已经能够<em>很多</em>做他们中的大多数人实际上永远不会做的事情。</p>

<p>但是假设你有不同的感觉。然后你可以在每个相关的 ViewController 中显式地实现 <code>appDelegate</code> (以违反 DRY 为代价)。</p>

<p>或者(这是很酷的部分)你可以声明一个协议(protocol)和一个协议(protocol)扩展,并且只有相关的 ViewController 采用它。所以,这是你的 <em>AppDelegate.swift</em> 文件:</p>

<pre><code>import UIKit

protocol AppDelegateAccesser {}
extension AppDelegateAccesser {
    var appDelegate: AppDelegate {
      return UIApplication.shared.delegate as! AppDelegate
    }
}

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    // ....
}
</code></pre>

<p>现在假设只有 MyViewController 类实际上需要访问应用程序委托(delegate)。那你就说</p>

<pre><code>extension MyViewController : AppDelegateAccesser {}
</code></pre>

<p>这会将 <code>appDelegate</code> 注入(inject) MyViewController 但没有其他类。因此,您只需为需要访问应用程序委托(delegate)的每个 ViewController 执行此操作,而不是其他。与您最初提出的解决方案相反,我认为这是一个完全不必要的练习,但它确实解决了仅将代码注入(inject)某些类的问题。</p>

<hr/>

<p>注意:在 Swift 5 中,声明只有 UIViewController 子类可以采用此协议(protocol)是合法的。你可能会喜欢。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 扩展 UIViewController 以访问应用程序委托(delegate)是一种反模式吗?,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/54540087/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/54540087/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 扩展 UIViewController 以访问应用程序委托(delegate)是一种反模式吗?