🐧🐧🐧iOS開発で誰も教えてくれなかったけど当たり前にやっているSwiftの書き方🐧🐧🐧

「誰も教えてくれなかった」ってタイトルですが、僕iOS開発に関しては独学でしかやってないので、よく考えたら誰にも教わってないですね🐧🐧🐧
まあなんか、本読んでもあんまり明示的には書いてないけど、「皆当たり前にやってるやん！」と思ったことを書いていきます。
（どこかに書いてあるのを見落としただけかもしれませんが）

# delegateで要求されているprotocolはextensionで書く
ルールではないですが、慣習的にextensionで各protocolごとに分離して書いた方がきれいです。

```swift
extension SampleMapViewController: MKMapViewDelegate {

    func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
    //do something
    }
```

# プロパティの型をOptionalにするとイニシャルしなくてよい
Swiftの制約として、クラスに紐づくプロパティは全部イニシャライザで初期値が与えられていないといけません。
基本的には初期化しろ、なんですが、これがタイミングによってはしんどいときがあります。
そういう場合、Optional型を指定すると、イニシャルしなくてよくなります。

```swift
class Hoge {
    var hoge: String?
    
    init() {
        //hogeは初期化しなくてもよい
    }
}
```

# オプショナルチェーンはnilだと実行されない
これもOptional型の理解が足りてなかった話なのかもしれませんが、
オプショナルチェーンを使った場合、nilだと実行されません。
具体例を見ると、

```swift
var str: String?
 
print(str?.uppercaseString) // nil（uppercaseStringは処理されず）
```

str?の中身がnilでなければ実行、nilだったら実行スキップのif文を書いているのと同様の挙動となります。
つまりnilの際はプロパティアクセス・メソッドは実行されないので、考慮しなくてOKです。

# frameを更新すると描画位置が更新される
コードでView要素の位置を変更する場合、setNeedDisplay()が都度要るのかとか思ってしまったのですが、
基本的にはframeの座標更新をすれば、描画位置は更新されます。

# コンピューテッドプロパティは呼ぶたびに再計算が走る
これも「誰も教えてくれなかった」というよりは理解不足系ですが、コンピューテッドプロパティは呼ぶたびに再計算します。
そして計算結果は保持されません。

僕は「初回に計算処理が走り、計算結果を出す。２回目以降はそれを上書き」だと勘違いしていました。
今までやった言語（古めのJava）だと、こんなプロパティはなかったので、「そもそも値を保持していない」というのが理解できていませんでした。

# フォースアンラップしていいケースは（ほとんど）ない
Swift使い始めの頃はしょっちゅうフォースアンラップで値を取り出していたのですが、
勉強しはじめて、フォースアンラップしていいケースはほとんどないことに気づきました。
特に本番環境で使うコードであれば、コードが冗長になっても、安全に取り出しましょう。

Appleの公式で、フォースアンラップを使っている例を１個だけ発見しました。

```swift
// Imported from C
func strlen(_ __s: UnsafePointer<Int8>!) -> UInt

let length = uint8Pointer.withMemoryRebound(to: Int8.self, capacity: 8) {
    return strlen($0)
}
// length == 7
```
https://developer.apple.com/documentation/swift/unsafemutablepointer

（2020/02/04追記）
２個目発見しました。
perform(_:)です。

https://developer.apple.com/documentation/objectivec/nsobjectprotocol/1418867-perform

やっぱ雰囲気的には低レイヤの処理のときにだけ使っている感じですかね。

# クロージャは基本弱参照でもたせる
```swift
URLSession.shared.dataTask(with: url, completionHandler: { [weak self] (data, responce, error) in
    let hoge = self?.hoge
}
```
絶対に循環参照なんてしないよ！　と言い切れる場面ならいいですが、
正直そんな場面ってあんまない気もするので、クロージャ書くときで上位スコープへのアクセスがあるときは全部弱参照でいいんじゃないかな〜って思ってます。
（逆に弱参照にした結果、困ることってクロージャ内のコードが少し増える、くらいしかないので）

# 配列・辞書を処理するクロージャは簡略記法を活用する
どうしても$0とか$1とかいう表記が最初苦手でしたが、特に高階関数（mapとかfilterとかforEachとか）使うようなケースは、
配列・辞書の要素取り出しとかは、$0とか簡略記法で書く方がスタイリッシュな気がします。
（ここは議論の余地があるかもですが）

# Setterだけprivateにできる
下記の書き方で、Setterだけprivateにできます。

```swift
private(set) var hoge: Bool
```

# プロパティの初期化でクロージャを使う
最初コンピューテッドプロパティと混同してしまいましたが、
（というかこの書き方のせいでコンピューテッドプロパティの挙動を誤解した）
クロージャを使って、プロパティの初期化が可能です。

```swift
let hoge = { return "hoge" }()
```

この例だと完全に無意味な代入ですが、初期値入れる際にちょっと前提処理が必要なときなどに便利です。
クロージャの真後ろに()があるので、クロージャを代入しているのではなく、クロージャの実行した後の戻り値を代入しています。

# 型推論を積極的に使う
特に勉強始めたばかりの頃、こんな書き方をよくしてました。

```swift
let hoge: String = "hoge"
```

代入する値が明らかにString型なのに、「明示的に書いた方がわかりやすいのかな？」という感覚があり、「変数名: 型」を書いていました。
しかし基本的には、Swiftの型推論機能を使って、省略したほうがスタイリッシュです。
例外は下記みたいなケース。

```swift:書かなきゃいけない例
let float: Float = 1.0
let cgfloat: CGFloat = 1.0
let double: Double = 1.0
```

# Swiftは関数型の思想が入っている
オブジェクト指向というよりかは関数型っぽく書く方がモダンな感じがします。
（要出典）

# enumを積極的に使う
使える場面であれば、enumを積極的に使いましょう。

# まとめ
終盤雑になりましたが、以上が僕の「誰か教えてよ〜〜〜」となったSwiftの書き方でした。
何かの役に立てば幸いです。
誤字脱字/誤りありましたら、ご指摘/編集リクエストお願いします🙏🙏🙏