만재송
[iOS] 프로토콜(Protocol)과 델리게이트(Delegate) 본문
프로토콜(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 의 기능은 그림으로 정리했습니다.
'프로그래밍 > iOS with Objective C' 카테고리의 다른 글
[iOS] 모달(Modal) 이란? (0) | 2019.08.08 |
---|---|
[iOS] 네비게이션(Navigation) 이란? (0) | 2019.08.08 |
[iOS] UIButton 과 UILabel (0) | 2019.08.08 |
[iOS] 스토리보드(Storyboard)란? (0) | 2019.08.08 |
[iOS] ViewController 생명주기 (0) | 2019.08.08 |