Manjusaka

Manjusaka

好与坏,Swift面面观 Part2

不久之前,在我写的良い Swift、悪い Swift — パート 1一文中,我介绍了一些关于在 Swift 里怎样去写出優れたコード的小技巧。在 Swift がリリースされてからの 2 年間、私はベストプラクティスをしっかりと習得するために多くの時間を費やしました。詳細については、この記事をご覧ください:良い 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)

            // 制約を設定
        }
    }

上記のコードで、私があまり好きではないのは、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)

            // 制約を設定
        }
    }

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

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

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

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

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

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

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