본문 바로가기

PDA&Mobile

[팁] iOS Protocol & Delegate(프로토콜 & 델리게이트) 구문 정리

* 본 포스트의 내용은 MissFlash가 학습용도로 정리한 것입니다. 내용은 정기적으로 업데이트되니 퍼가기보다는 링크나 트랙백을 이용해주시면 감사하겠습니다.

일반적으로, 상위 클래스에서 하위 클래스의 메소드를 실행하는데는 어려움이 없지만 하위 클래스에서 상위 클래스의 메소드를 실행할 때는 약간의 테크닉이 필요합니다. 이번 포스트에서 소개할 프로토콜 & 델리게이트 구문이 바로 그 주인공이죠. 물론, 최상위 계층의 앱 델리게이트를 이용해도 같은 효과를 볼 수 있지만... 실행하려는 메소드가 특정 클래스에 국한될 경우일 때는 프로토콜 & 델리게이트 구문이 더욱 효과적이라고 할 수 있습니다.

아래는 Planner S를 만들면서 실제 사용한 코드 중 일부를 정리한 것인데요... 코드중 빨간색 부분을 중점적으로 살펴보시면 되며 간단한 설명은 아래를 참고하시기 바랍니다.
  • 상위 클래스 : ShotView.h, ShotView.m
  • 하위 클래스 : ShotMemberList.h, ShotMemberList.m
  • 상위 클래스에 하위 클래스의 델리게이트를 추가 : ShotFollowDelegate
  • 상위 클래스에 하위 클래스의 프로퍼티 추가(반드시 필요한 것은 아님) : shotMemberList
  • (상위 클래스에) 하위 클래스에서 실행하고 싶은 메소드 추가 : - (void) refreshFollow:(NSString *)type;
  • 하위 클래스 인스턴스의 delegate 속성 설정 : shotMemberList.delegate = self;
  • 하위 클래스 인스턴스를 release 하지 말것!
  • 하위 클래스에 프로토콜 및 메소드 선언 : @protocol ShotFollowDelegate <NSObject>; - (void) refreshFollow:(NSString *)type; @end
  • 하위 클래스에 delegate 프로퍼티 추가 : id<ShotFollowDelegate> delegate;
  • 하위 클래스에서 delegate 프로퍼티를 통해 원하는 메소드 실행 : [self.delegate refreshFollow:@"YES"];

ShotView.h
#import <UIKit/UIKit.h>
#import "ShotMemberList.h"

@ interface ShotView : UIViewController <ShotFollowDelegate> {
ShotMemberList* shotMemberList;
}
@ property (nonatomic, retain) ShotMemberList* shotMemberList;
- (void) refreshFollow:(NSString *)type;
@ end

ShotView.m
#import "ShotView.h"

@ implementation ShotView
@ synthesize shotMemberList;

- (void) refreshFollow:(NSString *)type{
    // Codes are here...
}

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    shotMemberList = [[ShotMemberList alloc] init];
    shotMemberList.delegate = self;
    [self.navigationController pushViewController:shotMemberList animated:YES];

    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
}

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
}

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)dealloc {
    // Delegate/Protocol 사용시 인스턴스를 release 하면 안됨
    //[shotMemberList release];
    [super dealloc];
}

@ end

ShotMemberList.h
#import <UIKit/UIKit.h>

@ protocol ShotFollowDelegate <NSObject>;
- (void) refreshFollow:(NSString *)type;
@ end

@ interface ShotMemberList : UIViewController {
    id<ShotFollowDelegate> delegate;
}
@ property (nonatomic, assign) id<ShotFollowDelegate> delegate;

@ end

ShotMemberList.m
#import "ShotMemberList.h"

@ implementation ShotMemberList
@ synthesize delegate;

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [self.delegate refreshFollow:@"YES"];
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
}

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)dealloc {
    [delegate release];
    [super dealloc];
}

@ end