@peccul is peccu

(love peccu '(emacs lisp cat outdoor bicycle mac linux coffee))

= Objective-Cでprotocolとかdelegateとかいい感じに警告をなくす

[2011-06-10 20:38:44]
>>>[objective-c]
>>>[cocoa]
>>>[ios]
>>>[iphone]

HogeクラスがFugaクラスのインスタンスをもってて,FugaクラスがHogeクラスのメソッドを呼び出したい.ってことが地味にある.
FugaのdelegateにHugaをsetDelegateしてたけどプロトコルの書き方知らんくてずっと警告を無視してた.

ようやく重い腰を上げたのでその記録.

概略

クラスは二つ

Fugaクラスのインスタンスを持ってて,そのインスタンスからHogeメソッドを呼びたい.

  • Fuga

Hogeクラスにinitとかされてインスタンスになる.時々Hogeクラスのメソッドを呼びたい.

サンプル

こんな感じに書くと,Fuga側からHogeメソッドを呼び出せます.

Fuga.h
#import <Foundation/Foundation.h>

// FugaDelegateっていうプロトコルはこんなメソッドを実装してね
@protocol FugaDelegate
-(void)callFromFuga;
@end

@interface Fuga : NSObject{
    // delegateはFugaDelegateプロトコルに従うインスタンスやで
    id <FugaDelegate> delegate;
}
@property (retain, nonatomic) id <FugaDelegate> delegate;

@end
Fuga.m
#import "Fuga.h"

@implementation Fuga

@synthesize delegate;

-(void)someMethod{
    // こいつがCallFromFugaを呼び出す
    // delegateはFugaDelegateプロトコルに従うのでcallFromFugaを見つけられる
    [delegate callFromFuga];
}

@end
Hoge.h
#import <Foundation/Foundation.h>
#import "Fuga.h"

// FugaDelegateっていうプロトコルを実装しまっせ.っていう宣言
@interface Hoge : NSObject <FugaDelegate> {
    Fuga *fugafuga;
}

@end
Hoge.m
#import "Hoge.h"

@implementation Hoge

-(id)init{
    if((self = [super init]) != nil){
        // fugafugaのdelegateは私(Hoge)ですよ.って教える
        fugafuga = [[Fuga alloc] init];
        [fugafuga setDelegate:self];
    }
    return self;
}

// Fugaから呼ばれる
-(void)callFromFuga{
    NSLog(@"called from Fuga");
}

@end

謝辞

すぎゃーんさんのページのおかげで理解できました.ありがとうございます.
protocolと関連させたクラスの定義方法 - すぎゃーんメモ