【Xcode】初心者向け簡単なデリゲート実装サンプル【Objective-C】


Objective-Cのデリゲート実装でつまづきました。私みたいに、まずはどこに何を書くかサンプルコードが無いとよく分からないよ！って人の為に残しておきます。
概念的なことは他の方々が纏めてくださっているのでここでは割愛します。

※初心者による初心者向けの記事です。
※間違っている部分があったら指摘して頂けると幸いです。

##デリゲートって？
そもそもデリゲートってなんやねん・・・ということで言葉の意味から調べました。
デリゲートという言葉の意味は<strong>委譲</strong>。つまり
**デリゲート** = **『あと頼むわ！』** ってことです（多分）

##やりたいことの流れ##


1. 「ViewController」から「MySampleクラス」の「throwDelegateメソッド」を呼び出す
- 「throwDelegateメソッド」でデリゲートを「ViewController」の「catchDelegateメソッド」に渡す
- 「catchDelegateメソッド」の処理を実行する

	(protocol名は「NewDelegate」とします)



##実装手順##


<strong>1.	プロジェクトを作成</strong>
<strong>2.	XcodeのメニューからFile → New → File… → Cocoa Touch Classを選択し、Classに`MySample`と入力する。Subclass of:はそのままNSObjectを使用する。</strong><br>
（MySampleはNSObjectのサブクラスですよ〜　＝ NSObjectは<strong>スーパークラス</strong>ですよ〜　＝　MySampleはNSObjectを<strong>継承</strong>しますよ〜）
<strong>3.	MySample.hの`#import`と`@interface`の間に`@protocol`を記述する</strong>

```Objective-C:MySample.h
#import  <Foundation/Foundation.h>

//ここから追記
@protocol NewDelegate <NSObject>
@optional
-(void)catchDelegate;
@end
//ここまで

@interface MySample : NSObject

@end      
```

`@required`　：実装が必須
`@optional`　：実装が必須ではない
指定なし 　  &emsp;： = `@required`（実装が必須）


<strong>4.	MySample.hの`@interface`に`@property`を記述する</strong>

```Objective-C:MySample.h
#import  <Foundation/Foundation.h>

@protocol NewDelegate <NSObject>
@optional
-(void)catchDelegate;
@end

@interface MySample :NSObject
@property(nonatomic,assign)id<NewDelegate> delegate;	//追記
@end
```

<strong>5.	MySample.hの`@interface`に-(void)throwDelegateを記述</strong>

```Objective-C:MySample.h
#import  <Foundation/Foundation.h>

@protocol NewDelegate <NSObject>
@optional
-(void)catchDelegate;
@end

@interface MySample :NSObject
@property(nonatomic,weak)id<NewDelegate> delegate;
 -(void)throwDelegate;	//追記
@end
```

<strong>6.	MySample.mの`@implementation`にthrowDelegateメソッドを記述する</strong>

```Objective-C:MySample.m
@implementation MySample
//ここから追記
-(void)throwDelegate{
    NSLog(@"あとは頼む！");
    [self.delegate catchDelegate];
}
//ここまで
@end
```

指摘を頂いたので以下のように変更しました。

```Objective-C:MySample.m
@implementation MySample
//ここから追記
-(void)throwDelegate{
    //catchDelegateメソッドが呼び出せるかどうか
    if ([self.delegate respondsToSelector:@selector(catchDelegate)]) {
        NSLog(@"あとは頼む！");
        [self.delegate catchDelegate];
    }
}
//ここまで
@end
```

<strong>7.	ViewController.mにMySample.hをimportする</strong>

```Objective-C:ViewController.m
#import "ViewController.h"
#import "MySample.h" //追記
```

<strong>8.	ViewController.mの`@interface`にデリゲートを指定</strong>

```Objective-C:ViewController.m
@interface ViewController ()<NewDelegate>
```

<strong>9.	ViewController.mでMySampleクラスのインスタンスを生成しデリゲートを渡す</strong>

```Objective-C:ViewController.m
- (void)viewDidLoad {
	[super viewDidLoad];
 	// Do any additional setup after loading the view, typically from a nib.
	
	MySample *mySample = [MySample new]; //追記
	mySample.delegate = self; //追記
	[mySample throwDelegate]; //追記
}
```

デリゲートを遷移させるメソッドと同じスコープでdelegate = selfする
<strong>10. ViewController.mにcatchDelegateメソッドを記述</strong>

```Objective-C:ViewController.m
-(void)catchDelegate{
	NSLog(@"ここからの処理を担当する！");
}
```

デリゲートに引数を持たせる場合
--
デリゲートに引数を持たせる場合は

<strong>1. 手順3に引数を追加する</strong>(MySample.h)

```Objective-C:MySample.h
-(void)catchDelegate : (NSString *)getValue1 : (NSString *)getValue2; //変更
 
```

<strong>2. 手順6に引数を追加する</strong>(MySample.m)

```Objective-C:MySample.m
-(void)throwDelegate{
  //catchDelegateメソッドが呼び出せるかどうか
  if ([self.delegate respondsToSelector:@selector(catchDelegate::)]) {
    NSString *toValue1 = @"渡したい値1"; //追記
    NSString *toValue2 = @"渡したい値2"; //追記

    NSLog(@"あとは頼む！");
    [self.delegate catchDelegate : toValue1 : toValue2]; //変更
  }
}
```
(catchDelegate::)の<Font color="blue">::に注意</font>

<strong>3. 手順10に引数と処理を追加する</strong>(ViewController.m)

```Objective-C:ViewController.m
-(void)catchDelegate : (NSString *)getValue1 : (NSString *)getValue2{ //変更
    NSLog(@"ここからの処理を担当する！");
	NSLog(@"getValue1の値:%@ getValue2の値:%@" , getValue1 , getValue2); //追記
}
```

##参考
[delegateデザインパターンによる情報通知(Objective-C)](http://qiita.com/sushichop/items/fa3b7b6101d4d576866b)
[Objective-Cのプロトコルとデリゲートのまとめ](http://shin.hateblo.jp/entry/2013/01/23/230123)
[[iOS] iOSのDelegateをしっかりと理解する](http://dev.classmethod.jp/smartphone/iphone/ios-delegate/)
[Objective-C 自分でdeleagteを書いた場合のrespondsToSelectorの使用方法（パラメータ有り阪）](http://servicein.hateblo.jp/entry/2012/02/26/165126)