AndroidエンジニアがSwiftをゼロから爆速学習した時のメモ

# はじめに
タイトルの通り。面倒なこと全部すっ飛ばしてkotlin脳をSwift脳にコンバートするためにとったメモ。読んだ本は[swift実践入門](https://www.amazon.co.jp/改訂新版-Swift実践入門-直感的な文法と安全性を兼ね備えた言語-PRESS-plus/dp/477419414X)。

あと関係ないですがちょうどFF14の漆黒のヴィランズ終わったところなのでたとえがソレっぽいです。

# 言語の基礎

## 変数宣言

```kotlin:kotlin
val enemyId = 10
var name : String = "フィリア"
```

```swift:swift
let enemyId = 10
var name : String = "フィリア"
```

**ポイント**

 - `val` -> `let` になった
 - 型推論の方法は同じ
 - varも同じ



## 関数周り(関数宣言と_)

```kotlin:kotlin
fun updateStatus(str:Int, int:Int, dex:Int) = ..

/*呼び出し*/
updateStatus(1,2, dex = 3)
```

```swift:swift
func updateStatus(str:Int,_ int:Int, dex:Int) = ..

/*呼び出し*/
updateStatus(1,2, dex: 3) //OK
updateStatus(1,2,3) //NG
```

**ポイント**

 - 関数宣言は`fun`→`func`に
 - **第二引数以降は「_」が宣言時についていないと呼び出し時にラベル指定が必須になる**
 - ラベル指定が`=`→`:`に
 - [参考ページ](https://shoken.hatenablog.com/entry/2014/06/18/151548)

## null,nullable

```kotlin:kotlin
val weaponId: Int? = null
val weaponName: String? = "ガンブレード"
val nullWeapon: String? = null

val nonNullWeapon = nullWeapon ?: "ガンブレード"
val connectWeapon = weaponName!! + nullWeapon!! 
```

```swift:swift
let weaponId: Optional<Int> = nil
let weaponId: Int? = nil
let weaponName: String? = "ガンブレード"
let nullWeapon: String? = nil


let nonNullWeapon = nullWeapon ?? "ガンブレード"
let connectWeapon = weaponName! + nullWeapon!
```

**ポイント**

 - `null` -> `nil`になった
 - kotlinでは`?`で表現してたOptionalを明示的にOptionalとしても書ける
 - `?:`は`??`になった
 - 強制アンラップは`!!`→`!`
 - その他は大体同じっぽい？



## Optional

```swift:swift
let none = Optional<Int>.none
let some = Optional<Int>.some(1)

```

**ポイント**

 - noneはOptionalで値がないケース、Scalaっぽい？
 - someはOptionalで値があるケース、Scalaっぽい？

## ジェネリクス的なやつ

```kotlin:kotlin
fun addDamage<T : Enemy>(enemy: T) = ..
```

```swift:swift
func addDamage<T : Enemy>(_ enemy : T) = ..
```

**ポイント**

 - 書き方一緒

## Listとか

```kotlin:kotlin
val enemyNames = listOf("フィリア", "ティターニア", "イノセント") //不変リスト
val itemLists = arrayOf("エーテル", "エクスエーテル") //可変リスト
itemLists.add("ハイエーテル")
```

```swift:swift
let enemyNames = ["フィリア", "ティターニア", "イノセント"]

let itemLists = Array<String>()
itemLists.append("エーテル")
itemLists.append("エクスエーテル")
itemLists.append("ハイエーテル")
```

**ポイント**

 - 不変リストは配列っぽい書き方
 - 可変リストはJavaっぽい書き方



## 連想配列(Dictionary)

```kotlin:kotlin
val enemyMap = mapOf(Pair(1,"ティターニア"), Pair(2,"フィリア"))
enemyMap[1] //ティターニア
```

```swift:swift
let enemyDic = [1: "ティターニア", 2: "フィリア"]
enemyDic[2] //フィリア
```

**ポイント**

 - 配列っぽい感じに書く。JSONっぽいかも？

## 型まわりの制約

```kotlin:kotlin
val hp:Int = 1234
val mp:Long = hp //NG
val mp:Long = Long(hp) //OK
```

```swift:swift
let hp:Int = 1234
let mp:Int64 = hp //NG
let mp :Int64 = Int64(hp) //OK
```

**ポイント**

 - kotlinと同じ。型が違ったら代入できない。要キャスト



## Tuple

```kotlin:kotlin
val pair = Pair(1,2)
pair.first //1
```

```swift:swift
let tuple2 = Tuple(1,2)
tuple2.0 //1
let tuple3 = Tuple(1,2,"そろそろFF14ネタ疲れてきた")
tuple3.2 //そろそろFF14ネタ疲れてきた

```

**ポイント**
 - ２個からTupleになったよ、３個でもTupleだよ。Scalaっぽい



## 制御文周り
kotlin側はもういいよね...
### if文

```swift:swift
if value <= 3 {

} else if value >= 3 {

} else {
}
```

**ポイント**
 - 括弧がないぞー！

### if-let

```swift:swift
let name = Optional("ティターニア")

if let n = name {
  print("名前は\(n)です")
} else {
  print(”nameless")
}
```

**ポイント**
 
 - letっぽいけどIf文っぽい。特に違和感はない、と思う

### guard

```kotlin:kotlin
fun someFunc() {
  val v = -1

  require(v > 0)
}
```

```swift:swift
func someFunc() {
  let v = -1

  guard v > 0 else {
   return
  }
  
}
```

**ポイント**

 - kotlinのrequireと似てる。kotlinはIllegalExp投げるけどSwiftはReturnするだけ



## switch,where

```swift:swift
let optA: Int? = 1

switch optA {
  case .some(let a) where a > 10:
    //10より大きく、aが存在
  default:
   //10以下かaが存在しない
}
```

**ポイント**

 - whereつけると条件式も追加できるぞ。kotlinなら内側にif書くしかなかったやつ



## ループ制御(for,for-calse, while, repeat-while)

```swift:swift
for elem in array { //foreachっぽいやつ
  print(elem)
}

for case 2..3 in array { //独特
}

while i>3 { //普通
}

repeat {
} while j>3 //いわゆるdo-while
```

**ポイント**

 - 特になし。そのまんま



## 制御構文(fallthrough,break,continue,return,throw)

```swift:swift
let a = 1
switch a {
 case 1:
   print("case1")
   fallthrough
 case 2:
   print("case2")
 default:
   print("def")
}

//出力結果
case1
case2
```

**ポイント**
 - `fallthrough`を使うと次に制御が飛ばせる。Obj-Cの兼ね合いで仕方なく追加された匂いがプンプンする。**基本使用禁止だろう**
 - break,continue,return,throwはkotlinと全く同じ



## ラベル

```swift:swift
label: for elem in [1,2,3] {
  for nestedElem in [12,3,4] {
    print("moge")
    break label
  }
}
```

**ポイント**

 - kotlinで言うところの`return@~`に近い挙動。指定したlabelのループを抜ける



## 遅延実行(defer)

```swift:swift
var count = 0

fun someFunc() -> Int {
  defer {
    count++
    print("second")
  }
  print("first")
  return count
}

print("call func")
someFunc()

//実行結果
call func
first
second
```

**ポイント**

 - 関数スコープを抜ける時に実行される。んだけど、これ**制御複雑になるから基本禁止では・・？**
 - [参考になりそうなページ](https://qiita.com/funafuna/items/cd48016553184c7d2104)

# 関数的なやつら

## 基本構文

```swift:swift
func 関数名(引数名1: 型, 引数名2:型) -> 戻り値の型 {
}
```

**ポイント**

 - `:`が`->`になった

## デフォルト引数

```swift:swift
func greet(user: String = "nameless") {
}
  print("hello \(user)")
```

**ポイント**

 - kotlinと同じ

## インアウト引数

```swift:swift
func greet(user; inout String) {
  if user.isEmpty `
     user = "nameless"
  }
  print("hello\(user)")
}

var user: String = ""
greet(user: &User)
print(\(user))

//実行結果
hellonameless
nameless
```

**ポイント**

 - いわゆる参照渡し。Obj-Cの名残がプンプンする。**つまり闇なので使わない方が良い**

## 可変長引数

```swift:swift
func print(strings: String...) {
  
}
```

**ポイント**

 - kotlinと同じで`...`をつける



## オーバーロード

```swift:swift
func getV():Int

func getV(i:Int):Int

func getV():String

```

**ポイント**
 - 引数違いのオーバーロードの他に、**戻り値が違うだけでもオーバーロードできる**
# クロージャ

**基本構文**

```swift:swift
{(引数名1 : 型, 引数名2 : 型...) -> 戻り値の型 in 
  //処理
}

let triple = {(x:Int) -> Int in
  x * 3
}

let quad = {(x:Int) -> Int in
  print(\(x))
  return x * 4
}

triple(3) //9
quad(3) //12

let closure:(Int) -> Int
func someFunction(x:(Int)->Int) {}

someFunction(closure)

var lengthCal: (String)->Int

lengthCal = {string in //型推論してくれるぞ
  return string.conut
}

lengthCal("abc") //3

let lengthOfString = {(string:String)->Int in
  return string.count
}

lengthOfString("abcd") //4

let isEqual:(Int,Int) -> Bool = {
  return $0 == $1
}
```

**ポイント**
 - kotlinで言うところの関数変数っぽいやつ
 - 処理が２行以上になるならreturn必須(quad)
 - 関数の引数にも使えるぞ！(someFunction)
 - 型推論も仕事してくれるぞ(lengthCal)
 - もちろん「クロージャを引数にとるクロージャ」もいける。(lengthOfString)
 - **デフォルト引数は使えないぞ！**
 - 引数名すら省略できるぞ！(isEqual)



## 関数引数としてのクロージャと属性指定

**基本構文**

```swift:swift
func 関数名(引数名: @属性名 クロージャの型) {
}
```

属性

 - **escaping**→引数のクロージャが関数のスコープ外で保持される可能性を示す
 - **autoclosure**→遅延評価を実現するための属性。付けると遅延評価してくれる

## トレイリングクロージャ

```swift:swift
func execute(param: Int,_ process:(Stirng)->Void) {
}

execute(1, {string in 
  print($0)
})

execute(1) { string in
  print($0)
}
```

**ポイント**

 - カリー化（部分適応だっけ・・・？）
 - AndroidStudioならサジェッションがくるやーつ


# 型とかその辺の話

```swift:swift
struct 構造体名 {
let value = 123
  func printVal() {
    print(self.value)
  }
static let signiture = "send from iPhone"
}

class クラス名 {
  class ver signiture = "send form Android"
}

enum 列挙型 {
}
```

**ポイント**

 - structがあるぞ。structは値渡し、classは参照渡し
 - 自身へのアクセスは`this`->`self`になってるぞ
 - structの場合は`companion Object`はないけど`static`があるぞ。意味はJavaのStaticと同じだ！(変数だけでなくメソッドにも使えるぞ)
 - 上記の`static`と同じ使い方ができるのがclassプロパティだ。違いは**クラスの方はオーバーライドできるぞ！**(staticはオーバーライドできない)
 - クラスとか構造体の中の変数は**プロパティ**と呼んでるぞ、C#と同じだ！

## プロパティオブザーバ

```swift:swfit
var プロパティ名 = 初期値 {
 willSet {
   //プロパティ変更前に実行される処理新しい値はnewValue変数としてアクセスできる
 }
 didSet {
   プロパティ変更後に実行される
 }
}
```

**ポイント**

 - kotlinにはなかった機能・・・かな、多分。
 - 挙動は書かれている通り。ログとか仕込む？


## レイジーストアドプロパティ

```swift:swift
lazy var インスタンスプロパティ名: 型 = 式
static lazy var インスタンスプロパティ名: 型 = 式

struct SomeStr {
  lazy var lazyV: Int {
    print("generate lazyV")
    return 2
  }
}
```

**ポイント**

 - SomeStrがインスタンス化された時ではなく、lazyVを参照した時に初期化される
 - kotlinの`lateinit var` と`by lazy`を足して２で割ったような挙動

## コンピューテッドプロパティ

```swift:swift
var プロパティ名: 型 { 
  get {
  }
  set {
  }
}
```

**ポイント**

 - kotlinのやつと一緒
 - set省略できる

## イニシャライザ

```swift:swift

struct Greeting {
  let to: String

  init(to:String) {
    selft.to = to
  }
}

struct Greeting2 {
  let to: String
  init?(to:Optional<String>) {
   self.to = to ?? nil
  }
}

class Mail {
  let from:String
  let to:String
  let title:String

  init(from:String, to:String, title:String) {
    //初期化
  }

  convinience init(from: String, to:String {
    self.init(from:from, to:to, title:"mogmeoge")
  }

  deinit {
    //クリーンナップ処理
  }
}

let greeting = Greeting("some one")
```

**ポイント**

 - kotlinの`init`関数とコンストラクタを足して２で割ったような機能。
 - 初期化の失敗がある場合は`init?`にする。失敗するときはnilを返す
 - convinience をつけるといわゆるセカンダリコンストラクタ
 - 全て初期化されているならばinit関数は不要(kotlinと同じ)
 - deinitはいわゆるonDestroyみたいなやつ。インスタンス破棄時に呼ばれるぞ

## サブスクリプト
コレクションの要素へのアクセスに使う

```swift
subscript(引数) -> 戻り値の型 { 
  get {
  }
  set {
  }
}

struct Progression {
  var numbers:[Int]
  subscript(index: Int)->Int {
    get {
      return numbers[index]
    }
    set {
      numbers[index] = newValue
    }
  }
}
```

**ポイント**

 - なぜコレクションだけ特別扱いしてしまったのか、コレガワカラナイ



## エクステンション

```kotlin:kotlin
fun String.log()　{
    print(this)
}
"test".log()
```

```swift:swift
extension String {
    func log() {
        print(self)
    }
    var enclosedString: String { 
       return "[ \(self) ]"
}
"test".log()
```

**ポイント**

 - `extention`修飾子をつける必要がある
 - もちろん定数に対しても拡張できる
 - [参考ページ](https://dev.classmethod.jp/smartphone/kotlin-swift-extensions/)

# 型の種類

## 値渡し、参照渡し

- `struct`→値渡し
- `class`→参照渡し

## 列挙型

```swift
enum Weekday {
     case sunday
     case monday
     case tuesday
     case wednesday
     case thursday
     case friday
     case saturday

     init?(japaneseName: String) {
         switch japaneseName {
         case "日": self = .sunday
         case "月": self = .monday
         case "火": self = .tuesday
         case "水": self = .wednesday
         case "木": self = .thursday
         case "金": self = .friday
         case "土": self = .saturday
         default: return nil
         }
     }
 }

enum 型名: ローバリューの型 {
  case ケース１ = ローバリュー
  case ケース２ = ローバリュー
  ..
}
```

**ポイント**

- initを用意するとkotlinでparserを書くのとと同じ感じ。こっちの方がスマートか？
- ローバリューは`enum Weekday(val name)`的なやつと一緒.Enumの要素と値を紐づける

# プロトコル
いわゆるinterfaceクラス

**基本構文**

```swift
protocol プロトコル名 {
  //定義
}

struct 構造体名 : プロトコル1, プロトコル2... {
  //中身
}

class クラス名 : スーパークラス名, プロトコル1, プロトコル2 {
  クラスの定義
}

extension エクステンションを定義する対象の型 : プロトコル名 {
  //定義
}
```

**ポイント**

- 素直な感じなのでそのまんま

## プロパティ

```
protocol プトロコル名 {
  var プロパティ名: 型 {get set }
}

protocol SomeProtocol {
  var id:Int {get}
}
struct SomeStr1: SomeProtocol {
  var id:Int
}

struct SomeStr2: SomeProtocol {
  let id: Int
}
struct SomeStr3: SomeProtocol { 
  var id: Int {
     return 1
  }
}
```

**ポイント**

- プロトコルでのプロパティは常にvar（継承先でそこはハンドリングするスタンス)
- setもプロトコルに書かれている場合、`let`には適応できない

## メソッド

```swift
protocol プロトコル名 {
  funcj 関数名(引数) -> 戻りの型
}

protocol SomeProtocol {
     mutating func someMutatingMethod()
     func someMethod()
 }

struct SomeStr: SomeProtocol {
 var number:Int
  mutaing func someMutatingMethod() -> Void {
    number = 1
  }

  func someMethod() {
    number = 1 //コンパイルエラー
  }
}

class SomeStr: SomeProtocol {
 var number:Int
  func someMutatingMethod() -> Void {
    number = 1
  }

  func someMethod() {
    number = 1 //OK
  }
}
```

**ポイント**

- structは値渡しになるので、プロパティを更新するときはmutaingが必要
- classは参照渡しなのでどちらも不要

## 連想型

```swift
protocol プロトコル名 {
  associatedtype 連想型名

  var プロパティ名: 連想型名
  func メソッド名(引数：連想型名)
  func メソッド名() -> 連想型名
}

protocol SomeProtocol {
     associatedtype AssociatedType

     // 連想型はプロパティやメソッドでも使用可能
     var value: AssociatedType { get }
     func someMethod(value: AssociatedType) -> AssociatedType{
       return 1
     }
 }

//typealiasで指定
struct SomeStr1 : SomeProtocol {
  typealias AssiosicatedType = Int

  var value: AssosiatedType
  func someMEthod(value: AssosicatedType) -> AssociatedType {
   return 1
  }
}

//自動型推論
struct SomeStr2 : SomeProtocol {
  typealias AssiosicatedType = Int

  var value: Int
  func someMEthod(value: Int) -> Int {
   return 1
  }
}

// ネスト型AssociatedTypeを定義することで要求を満たす
 struct SomeStruct3 : SomeProtocol {
     struct AssociatedType {}

     var value: AssociatedType
     func someMethod(value: AssociatedType) -> AssociatedType {
         return AssociatedType()
     }
 }
```

**ポイント**

- ジェネリクスに近い機能。歴史的背景を感じる
- プロトコルって言うくらいだからインタフェースと言うよりも型に依存しない処理だけを表現するのに使うイメージが強い

### 制約系

```swift
protocol プロトコル名 {
  associatedtype 連想型名 : プロトコル名またはスーパークラス名 where 連想型の制約
}

protocol Container {
     associatedtype Content
 }

 protocol SomeData {
     associatedtype Value
     associatedtype ValueContainer: Container where
         ValueContainer.Content: Equatable, ValueContainer.Content == Value
 }
```

**ポイント**

 - where句の後ろは連想型の制約を書く

### デフォルトの型指定

```
protocol SomeProtocol {
  associatedtype AT = Int
}
```

**ポイント**

- protocolの時点で指定する。これでデフォルトはIntになる

## プロトコルの継承周り

```swift
//プロトコルの継承
protocol プロトコルA : プロトコルB, プロトコルC...{
}

//クラス専用プロトコル
protocol プロトコル名: class {
} 
```

**ポイント**

- ほぼKotlinと一緒
- structとclassの２つがあるために、クラス専用プロトコルの宣言なんてものがあるぞ

## エクステンション

```swift
extension プロトコル名 {
  実装(Not 定義)
}

extention プロトコル名 where 型制約 {
  型制約を満たす場合に有効になるエクステンション
}
```

**ポイント**

 - 既存のプロトコルに対して**実装**を`Extension`できる
 - 型制約をつけた場合、条件を満たした場合のみ使える

## 標準ライブラリのプロトコル

 - `Equatable` -> イコール
 - `Comparable` -> 比較
 - `Iterator` -> イテレータ
 - `Sequence` -> 要素の列挙のためのプロトコル
 - `Collection` -> サブスクリプトによる要素へのアクセス
 - `Encodable,Decodable,Codable` -> エンコード、デコード


# ジェネリクス


**基本構文**

```swift
func 関数名<型引数> (引数名: 型引数) -> 戻り値の型 {
}

func someMethod<T> (value:T) -> T {
}

struct 構造体名<型引数> {
}

struct GenericStr<T> {
  var property:T
}

class クラス名<型引数> {
}

class GenericClass<T> {
  func someFunc(x: T) {}
}

enum　列挙型<型引数> {
}

enum GenericEnum<T> {
  case SomeCace(T)
}
```

**ポイント**

 - kotlinと同じ
 - ただしprotocolはassociatedtypeによって型が表現されるため、ジェネリクスが使えるのはstruct,class,enumの３つだけ

## 型制約

```swift
func 関数名<型引数: プロトコル名やスーパークラス名(引数)->戻り値の型 {
}

func 関数名<型引数: プロトコル名(引数)->戻り値の型 where 連想型: プロトコルやスーパークラス {
}

func 関数名<型引数1 : プロトコル1, 型引数2 : プロトコル2>(引数) -> 戻り値の型
     where プロトコル1の連想型 == プロトコル2の連想型 {

     関数呼び出し時に実行される文
 } 
```

**ポイント**

 - kotlinと(ほとんど)一緒
 - protocolが特殊運用になってるので、こっちもプロトコルについては特殊な記法になる
 - where句の後ろに連想型の制約を記載する

# モジュール
考え方はkotlinのマルチモジュールと同じ

## アクセス修飾子

 - `open`->モジュール内外で全てのアクセスOK
 - `public`->モジュール内外で全てのアクセスOK。**ただしモジュール外での継承やオーバーライドは禁止**
 - `internal`->同一モジュール内のみ(kotlinのinternalと同じ).**デフォルトのアクセスレベル**
 - `fileprivate`->同一ファイル内のみアクセス許可
 - `private`->対象の要素が属しているスコープ内のみ許可(kotlinのprivateと同じ)

## コメントについて

```swift
// 通常コメント
/*
*  通常コメント
*/

/// ドキュメントコメント
/**
* ドキュメントコメント
*/
```

**ポイント**

 - 通常コメントはkotlinと一緒
 - ドキュメントコメントはkotlinで言うところのjavadocに近い. QuickHelpから見えるようになる


# 型の設計指針

## struct or class
- **基本`struct`を使え**
- **structのletがkotlinのval**に当たる。**classのletはkotlinのval**と同等では無い。
- `deinit`使いたいときはclassがいいかもよ
- **`abstract calss`という概念が存在しない**ので、表現する場合は`protocol`を使う必要がある
  - abstractクラスとして表現していた「継承先で共通に使える実装」は**protocolのextensionで実装する**
- classの継承は共通のストアドプロパティを使いたいときくらいにしか使わない

## Optional
 - kotlinと同じ設計思想

# イベント通知回り

## デリゲートパターン
- 普通のデリゲートパターン。protocolで宣言する
- 命名規則は`did<動詞>`と`will<動詞>`で**<動詞>がいつ実行されるか**を表現している.
- 慣習的に**UIKitで提供されているDelegateは第１引数がデリゲート元のオブジェクトを渡す**。これは名前空間としてオブジェクトを区別するため
- だいたいUIKitで提供されるやつがデリゲートパターンになっている

### 弱参照の解消
`weak`を変数の前につけると弱参照になる。弱参照になるとARCの参照カウントが0のまま更新されないようになる。

これは**delegateパターンを使うと第１引数にデリゲート元のオブジェクトを渡すために循環参照になる**。そのため、delegateオブジェクトに`weak`を作って弱参照にする必要がある。

## クロージャ(キャプチャリスト)

```swift
{[weak または unowned 変数名または定数名](引数) -> 戻り値 in 
  //処理
}

class SomeClass {
  let id: Int

  init(id: Int) {
     self.id = id
  }
}
let object1 = SomeClass(id:42)
let object2 = SomeClass(id:43)

let closure = { [weak object1, unowned object2] () -> Void in 
  print(type(of: object1))
  print(type(of: object2))
}

closure()

//実行結果
Optional<SomeClass>
SomeClass
```

**ポイント**

- **`weak`はメモリ解放を前提とした弱参照**.メモリ解放が前提(つまりnilの可能性がある)のでOptionalになる。クロージャ内でオブジェクトにアクセスする時点で解放されていたらnilが返る
- **`unowned`はメモリ解放を想定しない弱参照**.つまり参照時点では必ず参照元が存在している前提なのでオブジェクトそのまま。クロージャ内でオブジェクトにアクセスする時点で解放されていたらエラーになる
- 使い所はkotlinと同じ感覚でOK。(コルーチンとはちょっと違うかな)

### 使い分け

**循環参照を招かない場合**

- クロージャの実行時に参照するインスタンスが必ず存在する→キャプチャリストを使わない
- クロージャの実行時に参照するインスタンスが存在しなくても良い場合→`weak`

**循環参照を招く場合**(大雑把にはclosureの中でselfを参照してるかつclocure外でclosureのインスタンスを保持している)

- 参照するインスタンスが先に解放される可能性がある→`weak`
- 参照するインスタンスが先に解放される可能性がない→`unowned` or `weak`

### escaping属性
escapingをつけるとselfが必須になる＝循環参照に気付きやすくする。逆に言えばescapingがない＝循環参照がない、となる

```swift

var c: (() -> Void)? = nil

func execute(_ closure: @escaping () -> Void) {
         closure()
         c = closure
     }
```

## オブザーバー
どっちかってーっとイベントハンドラーの実装に近い。(≠RxのObserver)。イベントハンドラに登録(addObserver)して、登録された同名のイベントハンドラに通知をし(post)、登録されたイベントハンドラに通知を受け取る(handle)、終わったら登録解除(removeObserver)。

割とやりたい放題できるので危険な香りがする。

### selectorと`@objc`
`#selector`はObj-Cのセレクタ型のオブジェクトにデータを渡すための修飾子。つけるとselector型になる感じ.クラスキャストに近い？

`@objc`はメソッドにつけるとObj-Cからアクセスできるようになる.selectorとセットで使う感じ

```swift
#selector(型名.メソッド名)

@objc func メソッド名

class SomeClass {
  @objc func someMethod() {}
}

let selector = #selector(SomeClass.someMethod)
```

# 非同期処理
RxSwiftでよくね？

# エラー処理

## `Result<T,Error>`,`do-catch`,`defer`
`Result<T,Error>`型で返すパターンと、`do-catch`で実現するパターンがある。`Result`は非同期の処理用、`do-catch`は同期の処理用。

```swift
do {
  defer {
    doを抜けたら実行される
  }
   throw 的な何か
} catch {
  エラー処理.定数errorが参照できる
}
```

**ポイント**

- Resultは関数型のResultと同じ設計方針で同じ使い方
- `do-catch`は御察しの通り`try-catch`と同じ
- deferは`finally`に近い。必ず実行される系(ただしタイミングは違う)

## `throw`,`try`,`try!`,`try?`

```swift
func 関数名(引数) throws -> 戻りの型 {
  throwの可能性のある処理
}

func someMethod throw -> Int {
   throw XXError
}

do { 
  let i = try someMethod()
} catch {
  
}

let i = try! someMethod() // Int or エラー

if let i = try? someMethod() {} //Optional<Int>
```

**ポイント**

- javaでのメソッドの呼び元にエラーを返すやつ。
- イニシャライザにも使える
- 呼び元はエラーの発生する可能性のあるメソッドを呼ぶ場合は`try`が必要になる
- `try!`はエラーが絶対に発生しないぞ！という強い意志のもの実行する。`do-catch`が不要になる
- `try?`はOptionalが返るようになる。`do-catch`は不要になる

## `rethrow`

クロージャーがエラーを吐く場合は`rethrow`を使う。

```swift
struct SomeError: Error {}

 func rethorwingFunction(_ throwingClosure: () throws -> Void) rethrows {
     try throwingClosure()
 }

 do {
     try rethorwingFunction {
         throw SomeError()
     }
 } catch {
     error // SomeError
 }
```

**ポイント**

- 普通のthrowと一緒な使い方.
- クロージャがthrow投げるときに使う

## `fatalError`,`Never`

```swift
func randomInt() -> Int {
  fatalError("未実装だぞ")
}


いわゆるアプリ終了系のエラー.`Never`は値を返さず、それ以降の処理を実行しない(ちなみにVoidは空のTupleを返す).

## `assert`,`assertionFailure`
いわゆるアサーション

```swift
func format(minute:Int, second: Int) -> String {
   assert(second < 60, "secondは60みまんで")
   return "〜〜"
}

func printSeason(month:Int) {
  swiftch month { 
   ..
   default:
     assersionFailure("呼ばれたらダメなやつ")
  }
}
```

**ポイント**

- assertはリリース時には無効になる
- 実行されたらアプリが終了する
- assertionFailureは呼ばれること自体がNGなやつ