현재 나는 iOS 프로그래밍을 가르치고 있으며, 내 머리를 감쌀 수없는 개념 중 하나는 위임입니다. 무엇입니까? 왜 그리고 어떻게 사용됩니까? 장점은 무엇입니까? 제가 읽고있는 책의 기술적 인 글은 이해하기 어렵습니다.
현재 나는 iOS 프로그래밍을 가르치고 있으며, 내 머리를 감쌀 수없는 개념 중 하나는 위임입니다. 무엇입니까? 왜 그리고 어떻게 사용됩니까? 장점은 무엇입니까? 제가 읽고있는 책의 기술적 인 글은 이해하기 어렵습니다.
답변:
이해하려면 이해해야 delegates
합니다 protocols
.
A protocol
는 서비스 계약과 같습니다. 객체 (주로 UIViewController
서브 클래스이지만 항상 그런 것은 아님)에 서명 할 때 "나에게 보내는 메시지를 뒷받침하는 논리를 제공하는 데 관심이있다"고 말합니다. 이는 NSNotificationCenter
관심 수준에 가입하는 것과 비슷하지만 위임을 사용하는 객체와의 차이점은 한 번 delegate
에 하나씩 만 가질 수 있으며 여러 객체가 같은 곳에 가입 할 수 있습니다 NSNotification
.
Apple은 위임을 광범위하게 사용합니다. 그러나 점점 더 많은 애플 이 다른 언어 blocks
와 비슷한 많은 API를로 옮기는 것을보고 callbacks
있습니다.
그러나 위임은 자체적으로 디자인 패턴이라고 주장하지만 위임은 MVC를 유지하는 데 도움이됩니다. 컨트롤러에서 모델을 분리하는 데 도움이됩니다. John Cartwright의 예와 같이 UITableView
행과 섹션을 표시하는 방법을 알고 있습니다. UITableViewCells
성능상의 이유로 재사용하는 방법을 알고 있습니다. 그것은 아는 다른 모든 것들을 UIScrollView
알고 있습니다. 그러나 어떤 셀을 표시 할지 모릅니다 . 해당 셀을 채울 내용 을 모릅니다 . 주어진 셀에 어떤 셀을 재사용 해야하는지 알 수 없습니다 NSIndexPath
. 어쨌든 이것은 컨트롤러의 역할이어야합니다. 위임을 통해 테이블 뷰는이 비보기 논리를 해당 책임이있는 개체로 오프로드 할 수 있습니다.
그 이상으로, 당신은 객체의 전체 수명 동안 하나의 델리게이트에 고정되지 않습니다. 주어진 데이터에 대해 여러 개의 데이터 소스를 쉽게 가지고 UITableView
필요할 때 런타임에 전환 할 수 있습니다.
따라서 위임은 개체에 대한 데이터를 제공하고 개체와의 상호 작용에 응답하는 데 유용합니다. 당신은 UIKit 클래스, 등을 많이 볼 수 있습니다 UITableView
, UIPickerView
, UICollectionView
, 등
그러나 위임은 개체간에 정보를 전달하려는 경우에도 매우 유용합니다. 자신의 프로토콜을 매우 쉽게 생성하고 자신의 개체를 등록하여 따라갈 수 있습니다. 또한 @required
기본적으로 프로토콜 방법이 있지만 일부 방법을 지정할 수 있습니다@optional
. 필요한 경우 유연성을 제공 할 수 있습니다. 부모보기 컨트롤러와 자식보기 컨트롤러가 있다고 가정 해 봅시다. 아마도 새 Containment API를 사용하여이 작업을 수행하고있을 것입니다. 일반적으로 부모에서 자녀에게 정보를 전달해야하는 경우 속성으로이를 수행합니다. 끝난. 그러나 자녀의 정보를 부모에게 다시 전달해야하는 경우 어떻게해야합니까? 아마도 자녀에게 무언가가 바뀔 수 있으므로 부모에게 알려야합니다. 물론 특정 값에 대해 KVO를 수행 할 수 있습니다. 그러나 버튼을 언제 눌렀는지 알고 싶을 수도 있습니다. 자식 뷰 컨트롤러에서 새 프로토콜을 작성하기 만하면됩니다
@protocol MyChildDelegate
- (void)buttonWasTappedInChild:(MyChildViewController *)childViewController;
@end
@interface MyChildViewController : UIViewController
@property (weak, nonatomic) id <MyChildDelegate> delegate;
@end
MyChildViewController에서 버튼을 누르면 대리인이 대리인 메시지에 응답하는지 확인하십시오 (필요하고 대리인이 메소드를 구현하지 않으면 충돌이 발생합니다. @optional
필요한 경우 메소드를 만들 수 있습니다). 그것:
- (IBAction)someButtonTapped:(id)sender {
if ([self.delegate respondsToSelector:@selector(buttonWasTappedInChild:)]) {
[self.delegate buttonWasTappedInChild:self];
}
}
그런 다음 MyChildViewController의 대리자를 부모 뷰 컨트롤러 로 설정 self
하고 구현 - (void)buttonWasTappedInChild:(MyChildViewController *)childViewController
하십시오. 팔! 자녀로부터 부모에게 정보가 전달되었습니다. 두 객체 사이의 관계는 부모 / 자식만큼 가깝지 않아도됩니다. 서비스 계약이므로 가입하는 객체가 필요한 메소드를 구현하여 거래의 끝을 유지하는 한 황금색입니다!
참고 : 대리인은 약한 / 할당 속성이어야합니다. 그렇지 않으면 개체를 할당 해제 할 수없는 유지주기를 입력하게됩니다.
도움이 되었기를 바랍니다!
대리자는 일반 개체에서 해당 기능을 구현하는 것이 의미가 없을 때 특정 기능을 구현하는 개체입니다. 의존성 주입의 한 형태입니다.
구체적인 예는 UITableViewDelegate 프로토콜을 참조하십시오. 테이블 뷰 행을 선택하는 작업은 앱마다 다르고 테이블 뷰마다 다르기 때문에 이러한 메서드는 테이블 뷰가 직접 구현하는 데 적합하지 않습니다. 델리게이트에는 메소드가 -tableView:didSelectRowAtIndexPath:
있으므로 구현하려는 모든 개별 조치에 대해 테이블보기를 서브 클래스 화하지 않고 행 선택을 처리하는 오브젝트를 작성할 수 있습니다.