【Objective-C】delegate 입문

8232 단어 iOSObjective-C
계기는 후배에게 delegate에 대해 가르칠 기회가 있었다는 것입니다.
처음에는 자신도 좀처럼 이해할 수 없었던 것을 기억했습니다.
delegate를 이해하는 데 도움이 될 수있는 기사가 되길 바랍니다.

이런 사람에게 추천


  • ViewController에 처리를 쓰면 iOS 앱 만들 수 있는 사람
  • 그러나 처리를 다른 클래스로 잘라내는 것은 어렵습니다.
  • 어쨌든 delegate라고 말은 알고 있지만, 자작 delegate는 만들 수 없다···라고 하는 사람

  • 쓰기


  • delegate 개요
  • delegate를 구현하는 방법

  • 환경


  • Xcode8.2
  • Objective-C

  • delegate 개요



    원래 delegate란 무엇일까요.
    Apple 문서에는 다음과 같이 쓰여져 있습니다.
    ( Objective-C 프로그래밍 개념 p.22)

    델리게이트(delegate, 위양)란, 어느 오브젝트가 프로그램중에서 이벤트에 조우했을 때, 그것을 대신해, 또는 제휴해 처리하는 오브젝트를 말합니다.

    delegate 이미지



    위의 "delegate되는 측"이라는 것이 delegate 객체입니다.
    "delegate 하는 쪽"은 delegate 객체가 누구인지는 모르지만, delegate 객체에 delegation 통지를 보냅니다.
    그리고, delegate 객체는 통지를 받은 후의 처리를 실시합니다.

    delegate 구현 방법



    그렇다면 delegate는 어떻게 코드로 만들 수 있습니까?
    덜컹 거리는 것보다 실제로 보는 편이 빠르다고 생각하기 때문에, 간단한 샘플 코드를 써 보았습니다.
    보충을 코멘트에 기재하고 있으므로 참고가 되면 다행입니다.

    delegate하는 쪽



    Hoge.h
    #import <Foundation/Foundation.h>
    
    /**
     HogeDelegate protocol
     */
    @protocol HogeDelegate <NSObject>
    /*
     @optionalではないメソッドは、delegate準拠先で必ず実装する必要があります。
     実装しないと警告が発生します。
     */
    @optional
    // @optional以下のメソッドはdelegate準拠先での実装は必須ではなくなります。
    - (void)didFuga: (NSString *)string;
    
    @end
    
    @interface Hoge : NSObject
    
    /**
     delegateオブジェクト
     */
    @property (weak, nonatomic) id <HogeDelegate> delegate;
    
    - (void)fuga;
    
    @end
    

    Hoge.m
    #import "Hoge.h"
    
    @interface Hoge ()
    
    @property (strong, nonatomic) NSString *hogeString;
    
    @end
    
    @implementation Hoge
    
    /*
     その他の実装は省略
     hogeStringに値が設定されていたりします。
     */
    
    - (void)fuga
    {
        /* 
         delegateメソッドが@optionalなので、respondsToSelectorで
         delegateオブジェクトがdelegateメソッドを実装しているか判定します。
         */
        if ([self.delegate respondsToSelector:@selector(didFuga:)]) {
            /* 
             delegationの通知を送ります。
             必要であれば、このように引数にHogeクラス側の情報を渡すことも可能です。
             */
            [self.delegate didFuga:self.hogeString];
        }
    }
    
    @end
    

    delegate되는 측



    ViewController.m
    #import "ViewController.h"
    #import "Hoge.h"
    
    @interface ViewController () <HogeDelegate> // HogeDelegateに準拠します
    
    @property (weak, nonatomic) IBOutlet UILabel *hogeLabel;
    @property (strong, nonatomic) Hoge *hoge;
    
    @end
    
    @implementation ViewController
    
    #pragma mark - Lifecycle
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        self.hoge = [Hoge new];
        // hogeのdelegateに自身を指定します。
        self.hoge.delegate = self;
        [self.hoge fuga];
    }
    
    #pragma mark - HogeDelegateMethod
    
    /**
     delegationの通知を受けとったら実行する処理
     delegateメソッドの具体的な実装を記述します。
    
     @param string Hogeクラス側から渡されてくる文字列
     */
    - (void)didFuga:(NSString *)string
    {
        // Hogeクラス側から渡されてくる文字列をラベルに表示します。
        self.hogeLabel.text = string;
    }
    
    @end
    

    이상, 간단하지만 delegate에 대해 소개했습니다.

    포인트 1



    다른 클래스에 처리해 주었으면 한다든가, 자기 클래스의 값 건네주고 싶다고 하는 때에 편리하다고 생각합니다.

    또, ViewController 의 이 처리의 정리를 다른 클래스에 잘라내고 싶다고 하는 경우에도 도움이 될 것입니다.
    ViewController로 해야 하는 처리는 delegate로 구현해, 그 외 로직등은 별 클래스로서 잘라낸다, 라고 할 수 있습니다.

    포인트 2



    샘플 코드의 Hoge 클래스는 ViewController 클래스를 모릅니다.
    ( #import "ViewController.h" 라든지 눈에 띄지 않네요)
    Hoge 클래스가 ViewController 클래스 이외에도 다양한 클래스에서 사용된다고 해도 그 클래스를 모르는 것이 좋습니다.
    이것은 각 클래스가 복잡하게 의존하는 혼돈의 상황을 피할 수 있음을 의미합니다.

    잘 사용하여 계속 개발하기 쉬운 앱을 만들어 주시면 좋겠습니다!

    좋은 웹페이지 즐겨찾기