Objective-Cのデリゲート実装でつまづきました。私みたいに、まずはどこに何を書くかサンプルコードが無いとよく分からないよ!って人の為に残しておきます。
概念的なことは他の方々が纏めてくださっているのでここでは割愛します。
※初心者による初心者向けの記事です。
※間違っている部分があったら指摘して頂けると幸いです。
##デリゲートって?
そもそもデリゲートってなんやねん・・・ということで言葉の意味から調べました。
デリゲートという言葉の意味は委譲。つまり
デリゲート = 『あと頼むわ!』 ってことです(多分)
##やりたいことの流れ##
- 「ViewController」から「MySampleクラス」の「throwDelegateメソッド」を呼び出す
-
「throwDelegateメソッド」でデリゲートを「ViewController」の「catchDelegateメソッド」に渡す
-
「catchDelegateメソッド」の処理を実行する
(protocol名は「NewDelegate」とします)
##実装手順##
1. プロジェクトを作成
2. XcodeのメニューからFile → New → File… → Cocoa Touch Classを選択し、ClassにMySample
と入力する。Subclass of:はそのままNSObjectを使用する。
(MySampleはNSObjectのサブクラスですよ〜 = NSObjectはスーパークラスですよ〜 = MySampleはNSObjectを継承しますよ〜)
3. MySample.hの#import
と@interface
の間に@protocol
を記述する
#import <Foundation/Foundation.h>
//ここから追記
@protocol NewDelegate <NSObject>
@optional
-(void)catchDelegate;
@end
//ここまで
@interface MySample : NSObject
@end
@required
:実装が必須
@optional
:実装が必須ではない
指定なし : = @required
(実装が必須)
4. MySample.hの@interface
に@property
を記述する
#import <Foundation/Foundation.h>
@protocol NewDelegate <NSObject>
@optional
-(void)catchDelegate;
@end
@interface MySample :NSObject
@property(nonatomic,assign)id<NewDelegate> delegate; //追記
@end
5. MySample.hの@interface
に-(void)throwDelegateを記述
#import <Foundation/Foundation.h>
@protocol NewDelegate <NSObject>
@optional
-(void)catchDelegate;
@end
@interface MySample :NSObject
@property(nonatomic,weak)id<NewDelegate> delegate;
-(void)throwDelegate; //追記
@end
6. MySample.mの@implementation
にthrowDelegateメソッドを記述する
@implementation MySample
//ここから追記
-(void)throwDelegate{
NSLog(@"あとは頼む!");
[self.delegate catchDelegate];
}
//ここまで
@end
指摘を頂いたので以下のように変更しました。
@implementation MySample
//ここから追記
-(void)throwDelegate{
//catchDelegateメソッドが呼び出せるかどうか
if ([self.delegate respondsToSelector:@selector(catchDelegate)]) {
NSLog(@"あとは頼む!");
[self.delegate catchDelegate];
}
}
//ここまで
@end
7. ViewController.mにMySample.hをimportする
#import "ViewController.h"
#import "MySample.h" //追記
8. ViewController.mの@interface
にデリゲートを指定
@interface ViewController ()<NewDelegate>
9. ViewController.mでMySampleクラスのインスタンスを生成しデリゲートを渡す
- (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する
10. ViewController.mにcatchDelegateメソッドを記述
-(void)catchDelegate{
NSLog(@"ここからの処理を担当する!");
}
デリゲートに引数を持たせる場合
デリゲートに引数を持たせる場合は
1. 手順3に引数を追加する(MySample.h)
-(void)catchDelegate : (NSString *)getValue1 : (NSString *)getValue2; //変更
2. 手順6に引数を追加する(MySample.m)
-(void)throwDelegate{
//catchDelegateメソッドが呼び出せるかどうか
if ([self.delegate respondsToSelector:@selector(catchDelegate::)]) {
NSString *toValue1 = @"渡したい値1"; //追記
NSString *toValue2 = @"渡したい値2"; //追記
NSLog(@"あとは頼む!");
[self.delegate catchDelegate : toValue1 : toValue2]; //変更
}
}
(catchDelegate::)の::に注意
3. 手順10に引数と処理を追加する(ViewController.m)
-(void)catchDelegate : (NSString *)getValue1 : (NSString *)getValue2{ //変更
NSLog(@"ここからの処理を担当する!");
NSLog(@"getValue1の値:%@ getValue2の値:%@" , getValue1 , getValue2); //追記
}
##参考
delegateデザインパターンによる情報通知(Objective-C)
Objective-Cのプロトコルとデリゲートのまとめ
[iOS] iOSのDelegateをしっかりと理解する
Objective-C 自分でdeleagteを書いた場合のrespondsToSelectorの使用方法(パラメータ有り阪)