非形式プロトコルのメモ

非形式プロトコルのメモ、あえて非形式を使う利点はなさそうだった
今は形式プロトコルでも@optionalで指定すれば実装は任意にできる。
実装を強制する場合は@requiredで指定する。
その方が明示的でわかりやすい
Objective-Cプログラミング言語(Apple公式)


Counter.h 非形式プロトコルを宣言するクラス

#import <Foundation/Foundation.h>

@interface Counter : NSObject
@property(nonatomic) id delegate;
- (void)count;
- (id)initWithDelegate:(id)delegate;
@end



Counter.m 非形式プロトコルを宣言するクラス
10数えたらdelegateに処理を委譲

#import "Counter.h"

// 非形式プロトコル Informal Protocol
// NSObjectのカテゴリとして宣言
@interface NSObject(CounterDelegate)
- (void)didFinishCountUpToTen:(Counter *)counter;
@end

@implementation Counter

- (id)initWithDelegate:(id)delegate
{
    self = [super init];
    if (self) {
        _delegate = delegate;
    }
    return self;
}

// 数を数えるメソッド
- (void)count
{
    static int nowCnt = 0;
    nowCnt++;
    // 10まで数えたら通知
    if (nowCnt >= 10) {
        if ([[self delegate] respondsToSelector:@selector(didFinishCountUpToTen:)]) {
            [self.delegate didFinishCountUpToTen:self];
        }
    }
}
@end



Player.h 非形式プロトコルを実装するクラス

#import <Foundation/Foundation.h>
@interface Player : NSObject
- (void)play;
@end



Player.m

#import "Player.h"
#import "Counter.h"
@implementation Player

// Counterを初期化して10回数える
- (void)play{
    Counter *counter  = [[Counter alloc] initWithDelegate:self];
    for (int i = 0; i < 10; i++) {
        [counter count];
    }
}

// 非形式プロトコルのメソッドを実装
- (void)didFinishCountUpToTen:(Counter *)counter
{
    NSLog(@"10回数え終わったよ!");
}
@end



main.m 実行確認用

#import <Foundation/Foundation.h>
#import "Player.h"
int main(int argc, const char * argv[])
{
    @autoreleasepool {
        Player *player  = [[Player alloc] init];
        [player play];
    }
    return 0;
}