Notice
Recent Posts
Recent Comments
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Today
Total
관리 메뉴

만재송

[iOS] 프로토콜(Protocol)과 델리게이트(Delegate) 본문

프로그래밍/iOS with Objective C

[iOS] 프로토콜(Protocol)과 델리게이트(Delegate)

만재송 2019. 8. 8. 16:50

프로토콜(protocol)은 선언만 되고 구현되지 않은 메서드를 말합니다. 다른 언어의 인터페이스와 같이 기능을 정의하고 구현하는 쪽은 프로토콜에서 정의한 메서드를 구현하면 됩니다.

 

프로토콜의 정의는 다음과 같습니다.

@protocol 프로토콜명
@required or @optional
- 메서드정의
@end

required 는 반드시 구현해야할 메서드를 정의하는곳이고 optional 은 구현해도되고 안해도되는 메서드를 정의하는 곳입니다.

 

보통 프로토콜을 자주쓰이는 방식이 델리게이트 패턴방식입니다. 델리게이트의 뜻은 대표, 위임하다 등 이있는데요. 여기서의 델리게이트는 대리자 라는 뜻으로 이해하시면 됩니다. 쉽게말해서 하나의 객체가 모든 일을 처리하는 것이 아니라 처리해야 할 일 중 일부를 다른 객체에 넘기는 것을 뜻 합니다.

 

어떻게 쓰이는지 예제를 만들어보겠습니다.

// ViewController.m
-(void)onTouchedComplete:(UITableViewCell*)cell {
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
    NSString *completeWork = [self.works objectAtIndex:indexPath.row];
    [self.works removeObjectAtIndex:indexPath.row];
    [self.completes addObject:completeWork];
    [self.tableView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 2)] withRowAnimation:UITableViewRowAnimationAutomatic];
}

해당코드는 ViewController 에서 버튼을 눌렀을때 어떠한 기능을 처리하는 메서드입니다. 이 기능을 WorkTableViewCell.m 에서 호출한다고 했을때 아래와같이 변수를 선언해서 메서드를 호출해야 합니다.

// WorkTableViewCell.m
@propery ViewController *viewController;

-(IBAction)onTouchedCompleteButton:(UIButton*)sender {
    [self.viewController onTouchedComplete:self];
}

이렇게 하면 지금 WorkTableViewCell 에서는 viewController의 onTouchedComplete 만 사용하고 있는데 viewController 의 모든 메서드나 프로퍼티에 접근이 가능한 상태가 됩니다. 굳이 접근 할 필요도 없는 메서드나 프로퍼티를 접근할 수 있게 되는거죠. 이때 delegate 패턴을 써서 필요한 메서드만 쓸 수있게 지정해줍니다.

// protocol 생성
@protocol WorkActionDelegate <NSObject>
-(void)onTouchedComplete:(UITableViewCell*)cell;
@end

먼저 인터페이스가 되는 프로토콜을 생성해줍니다. 위의 코드는 onTouchedComplete 메서드만 정의하고 있고요.

// ViewController.h
@interface ViewController : UIViewController <WorkActionDelegate>

@end

그리고 onTouchedComplete 이 선언되있는 ViewController 에 프로토콜을 <> 에넣어줍니다. 이뜻은 프로토콜에서 정의한 메서드를 구현하겠다는 뜻입니다. 기존에 onTouchedComplete 이 구현되어 있으니 에러는 나지않습니다. 이제 WorkTableViewCell 에서 delegate 변수를 선언해줍니다.

// WorkTableViewCell.h
@property (nonatomic, assign) id<WorkActionDelegate> delegate;

기존의 ViewController 타입에서 WorkActionDelegate인 변수를 선언해서 접근을 최소화 해줍니다. 마지막으로 delegate 변수에 ViewController 객체를 넣어주기만 하면 끝입니다.

// ViewController.m
cell.delegate = self;

self 를 넣는 이유는 프로토콜을 상속받고 구현하게 되는 상속받은 프로토콜로 형변환이 가능해지기 때문입니다.

 

이렇게 하면 WorkTableViewCell 에서는 ViewController 의 내부 기능을 알지못하면서 대리자인 WorkActionDelegate의 기능은 사용 할 수 있게 됩니다.

 

이렇게 만들지 않고도 iOS UI 에도 여러 델리게이트 프로토콜이 있습니다. 그중 테이블뷰에서 사용하는 UITableViewDelegate와 UITableDataSource 가 있습니다.

해당 델리게이트도 마찬가지로 <> 부분에 델리게이트를 넣어주고 필수적인 메서드를 구현해주면 됩니다.

// ViewController.h
@interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, WorkActionDelegate>

@end

// ViewController.m
self.myTableView.dataSource = self
self.myTableView.delegate = self

사용방법은 아까의 예시와 비슷하다고 생각하시면 됩니다. UITableViewDelegate와 UITableDataSource 의 기능은 그림으로 정리했습니다.

Comments