2017年5月15日月曜日

凛としてSwift (血闘編ノ弐)

SwiftLintネタ「凛としてSwift (血闘編ノ壱)」からの続きです。


trailing_semicolon

いうまでもなく、文末のセミコロンですね。
気をつけていたんですが意外に多かったです。Objective-C混じりのプロジェクトなので、反射的に入力してしまっていたんですね。
self.imageFoo.alpha = 0.3; //むむ、セミコロンが!
self.imageBar.alpha = 0.3;
self.imageFoo.alpha = 0.3 //取りましたよ
self.imageBar.alpha = 0.3


vertical_whitespace

2行以上、空の行がつづく時に出ます。
意図的に2行以上空けることはないので、これもうっかりですね。気がついていませんでした。
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    } 


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return notes.count
    }


trailing_comma

配列の最後の要素の後ろにカンマをつけるか否かです。
これは何というか、コーディングの流派というか、どっちもアリですし、だからこそSwiftの文法では両方OKになっているのだと思いますが、SwiftLintのデフォルトではカンマなしのようです。ここはSwiftLintに従うことにします。
        accidentials = [
            "picker_label_none",
            "picker_label_natural",
            "picker_label_sharp",
            "picker_label_flat", //←ここのカンマ
        ]
        accidentials = [
            "picker_label_none",
            "picker_label_natural",
            "picker_label_sharp",
            "picker_label_flat" //←取りましたよ

        ]


colon

コロンの後には空白を1個入れましょう、ですね。はい、その通りですね。
let hogeRequest:HogeRequest = HogeRequest()
let hogeRequest: HogeRequest = HogeRequest()


unused_closure_parameter

クロージャの使っていないパラメータをアンダースコアで省略すべきと。ふむ。
        UIView.animate(withDuration: TimeInterval(CGFloat(0.3)),
                       animations: { () -> Void in
                        pickerView?.center = offScreenCenter
        },
                       completion: { (Bool) -> Void in
                        pickerView?.removeFromSuperview()
        })
        UIView.animate(withDuration: TimeInt
erval(CGFloat(0.3)),
                       animations: { () -> Void in
                        pickerView?.center = offScreenCenter
        },
                       completion: { (_) -> Void in //←Boolをアンダースコアに変更
                        pickerView?.removeFromSuperview()
        })


weak_delegate

delegateパターンでは、循環参照によるメモリリークを避けるために弱参照にしなさいとのこと。
weakをつければいいのですが、それだけだと、"'weak' may only be applied to class and class-bound protocol types, not 'xxxDelegate'"のエラーが出るので、プロトコルにclassキーワードを追加して、クラス専用プロトコルにします。
protocol FooViewControllerDelegate {
    func fooViewDidDissmissed()
}

class FooViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

    var delegate: FooViewControllerDelegate? //←強参照
    var selectedPractice: Practice? //選択されているPractice
protocol FooViewControllerDelegate: class { //←クラス専用プロトコル
    func fooViewDidDissmissed()
}

class FooViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

    weak var delegate: FooViewControllerDelegate? //←弱参照にする
    var selectedPractice: Practice? //選択されているPractice


control_statement

これもまたObjective-C的うっかりです。
            switch (noteLanguage) { //←あれ、カッコが!
            case .english:
                name = "E♭"
            case .italian:
                name = "Mi♭"
            /* 省略 */
            case .japanese:
                name = "E♭"
            }
            switch noteLanguage { //←消しました
            case .english:
                name = "E♭"
            case .italian:
                name = "Mi♭"
            /* 省略 */
            case .japanese:
                name = "E♭"
            }


redundant_optional_initialization

オプショナル型の初期値はnilなので、わざわざnilで初期化する必要はないよ、です。
class HogeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    var finishTime: Date? = nil //←nilで初期化は冗長
class HogeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    var finishTime: Date? //←初期化を消しました


syntactic_sugar

いろんなケースがあるのかもしれませんが、ここではArray<hoge>()のシンタックス・シュガーである、[hoge]を使いなさいとのこと。

どうでもいいことですけど、syntactic_sugarなので「シンタクティック・シュガー」なんじゃないかなぁと思って辞書を引いたら、syntacticの訳に「シンタックスの」がありますね。syntaxの形容詞がsyntacticらしいです。ひょっとしてシンタックス・シュガーって和製英語だったりして?

    var transposingInstrumentKeys = Array<(TransposingInstrumentKey, String)>() //Arrayですね
    var transposingInstrumentKeys: [(TransposingInstrumentKey, String)] = [] //←配列っぽくね


unused_enumerated

enumeratedで変数が使われてないから、`.indices`とか使ってね、です。

こんな感じでenumeratedで回したけど、結局変数が使われないときにワーニングが出ます。これはコンパイラによるワーニングです。
"Immutable value 'h' was never used; consider replacing with '_' or removing it"
for (i, h) in hoge.enumerated() {
    /* 省略 */
    hoge[i] = piyo
    /* 省略 */
}

じゃあ、アンダースコアにすればいいかと修正すると、Lintがunused_enumeratedを検出します。
for (i, _) in hoge.enumerated() { // ←hをアンダースコアに
    /* 省略 */
    hoge[i] = piyo
    /* 省略 */
}

なるほどそりゃそうだ、です。
for i in hoge.indices { // ←ずぼらせずに、indicesを使いなさい
    /* 省略 */
    hoge[i] = piyo
    /* 省略 */
}


implicit_getter

コンピューテッドプロパティにおいて、セッタが不要なケースではgetキーワードが省略可能です。省略可能なものは省略してスッキリさせときや、です。
    var hoge: Int {
        get {
            return fuga + 10
        }
    }

もちろん、get{}を削除します。
    var hoge: Int {
        return fuga + 10
    }


まだまだ続くよ。「凛としてSwift (血闘編ノ参)」につづく。


♪♪♪


こちらもどうぞ。
凛としてSwift
凛としてSwift (血闘編ノ壱)
凛としてSwift (血闘編ノ参)
帰ってきた凛としてSwift(くるくる編)