Manjusaka

Manjusaka

好与坏,Swift面面观 Part2

不久之前,在我写的良い Swift、悪い Swift — パート 1一文中,我介绍了一些关于在 Swift 里怎样去写出优秀代码的小技巧。在 Swift 发布到现在的两年里,我花费了很长时间去牢牢掌握最佳的实践方法。欲知详情,请看这篇文章:良い Swift、悪い Swift — パート 1.

在这个系列的文章中,我将尝试提炼出我认为的 Swift 言語中良い部分と悪い部分。うーん、私も将来、優れた Swift が私を助けてくれることを望んでいます(うーん、君、見ないで、中央が君に決めたから、さあ、詩を二句読んでみて)。もし何か考えがあれば、または開発者としての人生経験を教えてくれたければ、Twitter で私に連絡してください。私のアカウントは ksmandersen です。

さて、無駄話はこれくらいにして、今日の授業を始めましょう。

guard 大法好、入 guard 保平安#

Swift 2.0 中, Swift 新增了一组让开发者有点陌生的特性。Guard 语句在进行防御性编程的时候将会起到不小的作用。(訳者注 1:防御的プログラミング(Defensive programming)は防御的設計の具体的な表れであり、プログラムの予期しない使用がプログラム機能に損害を与えないようにするためのものです。これは、ムルフィの法則の影響を減少または排除するための考え方と見なすことができます。防御的プログラミングは、悪用される可能性がある、いたずらや意図しない災害的影響を引き起こすプログラムに主に使用されます。出典はウィキペディア)。すべての Objective-C 開発者は防御的プログラミングに馴染みがあるかもしれません。この技術を使用することで、予期しない入力データを処理する際に、コードが異常を引き起こさないことを事前に確認できます。

Guard 语句允许你为接下来的代码设定一些条件和规则,当然你也必须钦定当这些条件(或规则)不被满足时要怎么处理。另外,guard 语句必须要返回一个值。在早期的 Swift 编程中,你可能会使用 if-else 语句来对这些情况进行预先处理。但是如果你使用 guard 语句的话,编译器会在你没有考虑到某些情况下时帮你对异常数据进行处理。

接下来的例子有点长,但是这是一个非常好的关于 guard 作用的实例。 didPressLogIn 函数在屏幕上的 button 被点击时被调用。我们期望这个函数被调用时,如果程序产生了额外的请求时,不会产生额外的日志。因此,我们需要提前对代码进行一些处理。然后我们需要对日志进行验证。如果这个日志不是我们所需要的,那么我们不再需要发送这段日志。但是更为重要的是,我们需要返回一段可执行语句来确保我们不会发送这段日志。guard 将会在我们忘记返回的时候抛出异常。

    @objc func didPressLogIn(sender: AnyObject?) {
            guard !isPerformingLogIn else { return }
            isPerformingLogIn = true

            let email = contentView.formView.emailField.text
            let password = contentView.formView.passwordField.text

            guard validateAndShowError(email, password: password) else {
                isPerformingLogIn = false
                return
            }

            sendLogInRequest(email, password: password)
    }

letguard 配合使用的时候将会有奇效。下面这个例子中,我们将把请求的结果绑定到一个变量 user ,之后通过 finishSignUp 方法函数使用 (这个变量)。如果 result.okValue 为空,那么 guard 将会产生作用,如果不为空的话,那么这个值将对 user 进行赋值。我们通过利用 where 来对 guard 进行限制。

    currentRequest?.getValue { [weak self] result in
      guard let user = result.okValue where result.errorValue == nil else {
        self?.showRequestError(result.errorValue)
        self?.isPerformingSignUp = false
        return
      }

      self?.finishSignUp(user)
    }

正直なところ、guard は非常に強力です。うーん、もしまだ使っていないなら、真剣に考えるべきです。

subviews を使用する際に、宣言と設定を同時に行う。#

前の一連の記事で述べたように、view を開発する際、私はコード生成を好む傾向があります。view の設定パターンに非常に慣れているため、レイアウトの問題や設定ミスが発生した場合、すぐにエラーの場所を特定できます。

開発中に、異なる設定プロセスを一緒にすることが非常に重要であることに気付きました。私の初期の Swift プログラミング経験では、通常 configureView 関数を宣言し、初期化時に設定プロセスをここに置いていました。しかし、Swift では プロパティ宣言コードブロック を利用して view を設定できます(実際、これを何と呼ぶのかは分かりませんが(逃げ))。

うーん、以下の例では、2 つの subviewsbestTitleLabelotherTitleLabel を含む AwesomeView ビューがあります。2 つの subviews は同じ場所で設定されています。設定プロセスは configureView メソッドに統合されています。したがって、labeltextColor プロパティを変更したい場合、どこを変更すればよいかはっきりと分かります。

    class AwesomeView: GenericView {
        let bestTitleLabel = UILabel().then {
            $0.textAlignment = .Center
            $0.textColor = .purpleColor()
        }

        let otherTitleLabel = UILabel().then {
            $0.textAlignment = .Center
            $0.textColor = .greenColor()
        }

        override func configureView() {
            super.configureView()

            addSubview(bestTitleLabel)
            addSubview(otherTitleLabel)

            // Configure constraints
        }
    }

上記のコードで、私があまり好きではないのは、label を宣言する際に付随する型ラベルであり、その後コードブロック内で初期化して値を返すことです。Thenというライブラリを使用することで、少し改善できます。この小さな関数を利用して、プロジェクト内でコードブロックとオブジェクトの宣言を関連付けることができます。これにより、重複した宣言を減らすことができます。

    class AwesomeView: GenericView {
        let bestTitleLabel = UILabel().then {
            $0.textAlignment = .Center
            $0.textColor = .purpleColor()
        }

        let otherTitleLabel = UILabel().then {
            $0.textAlignment = .Center
            $0.textColor = .greenColor()
        }

        override func configureView() {
            super.configureView()

            addSubview(bestTitleLabel)
            addSubview(otherTitleLabel)

            // Configure constraints
        }
    }

異なるアクセスレベルを使用してクラスメンバーを分類する。#

うーん、私にとって最近起こった重要なことは、クラスと構造体のメンバーを結合するために特別な方法を利用したことです。これは、以前 Objective-C で開発していたときに身につけた習慣です。私は通常、プライベートメソッドを一番下に置き、公共および初期化メソッドを中間に置きます。そして、プロパティを公共プロパティからプライベートプロパティの順にコードの上部に配置します。うーん、以下の構造に従ってコードを整理できます。

  • 公共プロパティ
  • 内部プロパティ
  • プライベートプロパティ
  • 初期化コンテナ
  • 公共メソッド
  • 内部メソッド
  • プライベートメソッド

静的 / クラスプロパティ / 定数の順に並べることもできます。人によっては、これに基づいていくつかの異なるものを追加するかもしれません。しかし、私にとっては、常に上記の方法でプログラミングを行っています。

さて、今回のエピソードはここまでです。もし良いアイデアや言いたいことがあれば、画面下部の連絡先を通じて私に連絡してください。もちろん、こんな方法でコインやバナナを投げて、私の文章をサポートし、購読することも歓迎します(大雲)。

次回予告:引き続き Swift のあれこれをお話ししますので、お見逃しなく、次回もお楽しみに。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。