天天看点

[译]iOS开发者在Swift中应避免过度使用

<b>本文讲的是[译]iOS开发者在Swift中应避免过度使用,</b>

<b></b>

为了达到本文的目的,我简化了工作中项目的代码,但所有核心的思想都保留着。一种我经常在swift里用的模式是:为了重用的配置写protocols(协议)和extensions(扩展),特别是有Uikit的时候

假设我们有一组视图控制器,每个控制器都需要一个 view model 和 一个“取消”按钮。每一个控制器需要各自响应

“cancel”按钮的点击事件。我们可以这样写:

如果就写成这样,那每个控制器都需要自己去添加和写一个一样的取消按钮。这样就会有很多一样的代码。我们可以通过扩展(用老的 <code>Selector("")</code> 语句)来解决:

现在每个符合协议的控制器都可以通过在<code>viewDidLoad()</code>里调用协议的<code>configureNavigationItem()</code> 方法来配置取消按钮,是不是好多了~我们的控制器看起来是这样的:

这仅是一个简单的例子,但我们可以想象通过这个方式制造更多复杂的配置。

把以上代码段升级到 Swift 2.2后,是这样的:

但现在我们有了个问题,一个新的编译错误

因为一系列的原因, 在原始的<code>ViewControllerType</code>协议中,我们并不能简单的给这个方法添加一个<code>@objc</code>修饰符。如果我们这么做了,那么所有的protocol都需要用<code>@objc</code>来标记,这将意味着:

所有这个protocol的父protocol都需要用<code>@objc</code>来标记。

所有继承自这个protocol的protocol都会被自动添加<code>@objc</code>。

我们在protocol中的结构体(<code>ViewModel</code>)不能用Objective-C来表示。

我们在这的例子很简单,但是想象一下更复杂的类依赖关系图,大量使用Swift的值类型和当这个协议处在多个协议的中间层时。把引入<code>@objc</code>作为解决方案真是app的末日。如果我们这样做,<code>@objc</code>这种做法会让我们的Swift代码毫无美感并变得乱糟糟。这会毁了所有的东西。

但是希望还是有的。

我们大可不必让为了让我们的Swifit代码能使用Objcetive-C的语法而使用<code>@objc</code>。

我们可以把protocol分解成多个protocol来去除<code>@objc</code>,然后我们再重组这些protocol。事实上,我们可以让编译器顺利编译和避免更改任何视图控制器的代码。

第一步,我们把protocol拆成2个。<code>ViewModelConfigurable</code> 和 <code>NavigationItemConfigurable</code>。把<code>ViewControllerType</code>里的extension放到<code>NavigationItemConfigurable</code>。

最终,我们可以把原<code>ViewControllerType</code> protocol定义成<code>typealias</code>。

和迁移到Swift2.2之前比一切都很正常,而且我们定义的原视图控制器也没有发生任何改变,没有东西被破坏。如果你曾经遇到类似的情况,或者你也想阻止<code>@objc</code>带来的破坏(你应该这么做),我强烈建议采用这个策略。

现在的代码,我还是觉得有点不爽,当然,针对这个问题,这就是最Swift化的答案。当Xcode突然开始提示你并且很快的应用它的修复方案依然会把所有都破坏掉。特别是当Xcode提供的修复方案正中你下怀的时候,这个时候,上面说的到的这类解决方案并不能立即很清楚。

最后,在做了以上那些更改之后,我意识到总的来说这其实是一个很好的解决方案。。没有什么理由在一个地方只用一个协议。像<code>ViewModelConfigurable</code> 和 <code>NavigationItemConfigurable</code>这两个协议分工明确。把不同的协议组合在一起始终都是最优雅、最适当的设计。

作者:donghuan1

链接:http://www.jianshu.com/p/b50a8ed6a00b

來源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

<b>原文发布时间为:2016年06月27日</b>

<b>本文来自云栖社区合作伙伴掘金,了解相关信息可以关注掘金网站。</b>

继续阅读