Xcode6 beta7にしたらDelegateでハマった(Swift, Xcode6 beta7)

# 0.追記

@susieyy さんのご指摘により解決致しました。
> Beta7にアップデートしてから、以下のコマンドは実施されましかたか？
> Beta7以前の中間コンパイルがあるとうまく動作しないです
> ```
> rm -rf ~/Library/Developer/Xcode/DerivedData
> ```

こちらを実行後、@objcを取り除いても、正常に動作しました。

![TinderStyleApp.gif](https://s3-ap-northeast-1.amazonaws.com/rendezvous-uploads/1/36/6642c744aa78ae76cf28dea6dd691b96.gif)

# 1.はまったこと
beta7に変更してから、これまでのDelegateだとうまく通らならかったのでメモ。
ハマったプロジェクトは、この前投稿したこちらの記事（[SwiftでTinderUIを実装してみた](http://qiita.com/kiiita/items/1c7f44add59b390ea786)）です。

# 2.beta7に対応する前のコード
「[SwiftでTinderUIを実装してみた](http://qiita.com/kiiita/items/1c7f44add59b390ea786)」にソースはほとんどおいているので（もしくは[Github](https://github.com/kiiita/TinderStyleApp/commits?author=kiiita)）、下記コードは必要な部分のみを抜粋しています。

今回関連するファイルは２つで、DraggableView.swiftとDraggableViewBackground.swiftです。
それぞれのファイルのサマリーを先に書いておくと、

- DraggableView.swiftでは、
 - 左右にスワイプされたときに起こるカードのアクションを定義している
 - DraggableViewBackgroun.swiftで使うためのDelegateを用意している

- DraggableViewBackground.swiftでは、
 - 背景やボタン、TinderUIのカードなどを描画する
 - カードに表示するテキストの生成、読み込みなどを行う
 - 左右にスワイプされたときに、表示するテキストを変える
 - DraggableView.swiftで用意されたprotocolを継承している

という感じです。

それで、下記コードがbeta7に対応する前のコードです。

```DraggableView.swift
// このファイルでは、TinderUIで言うところのカードのViewを生成し、ドラッグされた時の挙動を定義しています。

// Delegate先で使う予定のfunctionをprotocolで宣言しておきます。
protocol DraggableViewDelegate  {
    func cardSwipedLeft(card: UIView)
    func cardSwipedRight(card: UIView)
}

class DraggableView: UIView {
    
    var delegate: DraggableViewDelegate?
	.
	.
	.
	func rightAction() { // カードが右にドラッグされたときの処理
        var finishPoint: CGPoint = CGPointMake(500, 2*yFromCenter + self.originalPoint.y) // ドラッグされて、手が話された場所を変数に入れておく

		// カードが画面から消えるようにする
        UIView.animateWithDuration(0.3, animations: {
            self.center = finishPoint
            }, completion: { (value: Bool) in
                self.removeFromSuperview()
        })
        delegate?.cardSwipedRight(self) // ここで、delegate先のDraggableViewBackground.swiftに書かれている関数を呼び出す
        NSLog("YES")
    }

    func leftAction() { // カードが左にドラッグされたときの処理
        var finishPoint: CGPoint = CGPointMake(-500, 2*yFromCenter + self.originalPoint.y) // ドラッグされて、手が話された場所を変数に入れておく
		// カードが画面から消えるようにする
        UIView.animateWithDuration(0.3, animations: {
            self.center = finishPoint
            }, completion: { (value: Bool) in
                self.removeFromSuperview()
        })
        delegate?.cardSwipedLeft(self) // ここで、delegate先のDraggableViewBackground.swiftに書かれている関数を呼び出す
        NSLog("NO")
    }
	.
	.
	.
}
        
```

```DraggableViewBackground.swift

// このファイルでは、背景やその他のボタンを描画したり、カードの読み込みなどを行っています。
class DraggableViewBackground: UIView, DraggableViewDelegate{ // 先ほど用意したDelegateのためのprotocolを継承
	.
	.
	.
    
	// カードのViewを描画
    func createDraggableViewWithDataAtIndex(index: Int) -> DraggableView {
        var draggableView: DraggableView = DraggableView(frame:CGRectMake(30, 100, CARD_WIDTH, CARD_HEIGHT))
        draggableView.information.text = "\(exampleCardLabels[index])"
        draggableView.backgroundColor = UIColor.whiteColor()
        draggableView.delegate = self
        println("delegate = \(draggableView.delegate?)")
        return draggableView
    }

 	// 宣言していたProtocolにあるfunctionの中身を書いていきます。
    func cardSwipedLeft(card: UIView) {
        loadedCards.removeObjectAtIndex(0)
        if ( cardsLoadedIndex < allCards.count ) {
            loadedCards.addObject(allCards.objectAtIndex(cardsLoadedIndex))
            cardsLoadedIndex++
            self.insertSubview(loadedCards.objectAtIndex(MAX_BUFFER_SIZE-1) as UIView, belowSubview: loadedCards.objectAtIndex(MAX_BUFFER_SIZE-2) as UIView)
        }
        if (cardsLoadedIndex == 5) {
            self.result.text = "hoge"
        }
    }
    
    func cardSwipedRight(card: UIView) {
        loadedCards.removeObjectAtIndex(0)
        println("allCards = \(allCards.count)")
        println("cardsLoadedIndex is /(cardsLoadedIndex)")
        println(loadedCards.count)
        if ( cardsLoadedIndex < allCards.count ) {
            loadedCards.addObject(allCards.objectAtIndex(cardsLoadedIndex))
            cardsLoadedIndex++
            self.insertSubview(loadedCards.objectAtIndex(MAX_BUFFER_SIZE-1) as UIView, belowSubview: loadedCards.objectAtIndex(MAX_BUFFER_SIZE-2) as UIView)
        }
        if (cardsLoadedIndex == 5) {
            self.result.text = "huga"
        }
    }
	.
	.	
	.
}

```

beta7以前は、これで動いていたのですが、beta7にしたら、
```draggableView.dalegate? = self```がnilになり、
```delegate?.cardSwipedLeft(self) ```もそのままnilなので、
```func cardSwipedLeft```が呼び出されなくなってしまいました。

# 3.対策
色々と調べてたのですが、対策は、

```DraggableView.swift
@objc protocol DraggableViewDelegate  {
    func cardSwipedLeft(card: UIView)
    func cardSwipedRight(card: UIView)
}
```
というように```@objc```をprotocolの前につければさきほどのnilの部分に全てきちんとしたOptional型での値が入りました。

# 4.よくわからないこと
- @objcをつけることによってナゼ解消されるのか？
- そもそも設計上、このDelegateがベストプラクティスなのか？
ご存知の方、是非教えて下さいm(_ _)m