ObjectiveC Delegate

From 흡혈양파의 인터넷工房
Jump to navigation Jump to search
Objective-C 델리게이트 (Delegate)

출처
http://blog.daum.net/100booksclub/7924268


도입

언제나 새로운 랭귀지나 툴이 나오면..사람들이 가장 먼저 물어보는것이 델리게이트(Delegate)다.

참 요상하게도 이넘은 우리가 현대에서 프로그램밍을 할때 단한번이라도 안쓰면 프로그램이 돌아갈수가 없음에도 불구하고, 이것들에 대한 물음은 굉장히 많이 받는다.


특히, 이번 Objective - C 를 보면서 Objective -C 의 대표개발툴인 XCode가 조금 부실하구낭...

모르면 개발이 안될것 같다는 생각도 잠깐해봤다. 델리게이트는 매우 중요한것이므로, 사용법보다 이넘이 머하는넘인지 정확하게 이해하고 넘어가자.


델리게이트(delegate) 델리게이트함수 (delegate pattern)

델리게이트는 정말 중요한넘이면서도 우리에겐 늘~ 보이지 않는곳에서 그 역활을 충실히 하고 있는넘이다.

우리가 이넘을 모르는 이유는 몰라도 됐기때문이다. Windows 기반의 GUI 프로그래머라면.. 더더욱 그러할것이다. Windows 내의 Visual Studio 와 같은 툴들은 이제 왠만한 컨트롤들을 제공해줄뿐 아니라 모자라는것은 수많은 컴포넌트들이 이를 대신해준다.

물론, Windows 에서도 COM/COM+ 과 같은 컴포넌트기반의 프로젝트에선 델리게이트의 개념은 필수다.

delegate
명사 [|delɪgət]  동사 [|delɪgeɪt] 
1. (집단의 의사를 대표하는) 대표(자)   2. (권한・업무 등을) 위임하다   3. (대표를) 뽑다


프로그래머 입장에서 위의 사전적의미중에는 2번이 우리에게 적합한 용어라고 볼수 있당.

위임하다. 대리하다. 사실 갠적으론 이런사전적 의미자체가 우리를 헷갈리게 하는건 아닌가하는생각이 들지만..그래도 뜻이 그러니 사전적 의미도 곁들여서 설명토록 하겠다.

델리게이트 (Delegate) = 이벤트(Event) ??

델리게이트와 이벤트는 같은 말이다???

사실 좀 애매하고 그렇다고 답하기엔 무리가 있지만.. 이해를 돕기위해선 충분히 그렇다고 답할 수 있는 해답이다.

이것을 좀더 정확하게 표현하자면...

"이벤트함수(Event function) 는 델리게이트함수(Delegate pattern) 이다"

라고 표현 하는것이 가장 적절하다고 얘기할 수 있겠다.


그렇다면 델리게이트를 알려면 이벤트 함수를 알면되겠넹??

맞다. 우리는 이벤트 함수가 어떻게 호출되는지만 알면 델리게이트에 대한 이해는 완벽하게 끝난다고 볼수 있다. 쉽지 않은가? 델리게이트를 어렵게 생각했다면 용어에 대한 함정에 빠진것이다.


델리게이트의 정의

델리게이트는 정확히 표현하자면 객체간의 데이터(파라미터나 속성, 메서도 모두포함)통신시 전달자 역활을 하는것이 델리게이트다. 말이 좀 어렵다.

이걸 갠적으로 풀어서 적는다면

"특정객체에서 발생한 이벤트를 다른 객체에게 통보할 수 있도록 해주는 선언이다"

라고 정의할 수 있겠다. 이말도 그리 쉽게는 들리지 않겠지만.. 한번이라도 프로그램을 짜본사람이라면 상투적인 델리게이트의 정의보단 훨씬더 이해가 빠를거라 생각된다.

델리게이트가 가장 많이 쓰이는곳은 아무래도 이벤트처리시에 가장 많이 활용되고 사용되고 있다. 실제로 델리게이트는 이벤트를 처리하기위한 용도가 아니더라도 여러분야에서 사용될 수 있겠지만, 일반적인 프로그래머라면 거의 대부분이 이벤트발생처리를 돕기위해 사용하는것이 대부분일것이다. 따라서 델리게이트는 이벤트의 처리과정을 알면 델리게이트가 자동적으로 이해가 가게될것이다.


이벤트의 발생경로

우리는 늘~ 키보드와 마우스를 끼고 사는데... iPhone 같은경우엔 이런 이번트보다 한술 더떠서 투터치 터치텀이라는 이벤트까지 있어서.. 앞으로 우리는 이벤트에 묻혀서 살게되지 않을까 하는 생각이 든다. ㅡㅡ;


어쨌든..우리는 특정 이벤트하나를 쫒아가면서 델리게이트에 대한 정확한 개념을 잡아보자. 아마도 가장 많은 이벤트는 우리가 가장 흔히쓰는 onClick 이벤트를 모르는 사람은 없을테니 이넘을 한번 역추적 해보자.


우리는 Objective - C 를 배우고 있지만.. 이해를 돕기위해서 Windows 를 기준으로 추적해본다.

[MicroSoft Windows]

  1. 사용자가 왼쪽 마우스를 클릭한다.
  2. 마우스에서는 Serial(USB) 케이블을 통해 0X0001(그냥 예시다) 을 송신한다.
  3. 마우스에서 전송된 0x0001 을 Windows 가 RS232C 통신프로토콜을 이용해 수신한다.
  4. 수신된 데이터는 Windows 의 Message 센터로 마우스의 좌표와 0x0001 을 전송한다.
  5. ?
  6. 응용프로그램은 onClick 에대한 이벤트를 실행한다.


위의 이벤트 발생경로를 보고 이해가 안가시는분들은 없을거라 생각된다. 내가 만든 프로그램에 대한 모든 입력이벤트는 저러한 경로를 통해 명령을 실행하고 있는데... 5번이 빠져있다. 머가 빠졌을까??

[MicroSoft Windows]

  1. 사용자가 왼쪽 마우스를 클릭한다.
  2. 마우스에서는 Serial(USB) 케이블을 통해 0X0001(그냥 예시다) 을 송신한다.
  3. 마우스에서 전송된 0x0001 을 Windows 가 RS232C 통신프로토콜을 이용해 수신한다.
  4. 수신된 데이터는 Windows 의 Message 센터로 마우스의 좌표와 0x0001 을 전송한다.
  5. 델리게이트를 이용해 0x0001 에 대한 데이터가 onClick 에 대응됨을 알려준다.
  6. 응용프로그램은 onClick 에대한 이벤트를 실행한다.


적어도 프로그래머라면 onClick 이라는 이벤트를 안써본사람은 없을것이다. 하지만, 저 6번 항목에대해 깊이 생각해본사람은 없을것이다. 델리게이트의 용도와 사용시기에 대한 해답은 저것이 전부이다. 사용자의 프로그램과 다른 프로그램의 통신에도 델리게이트의 역활은 눈이 부시다.


이벤트 발생의 구체적인 예시

위에서 추적한 경로중에서 5번이 델리게이트에 해당하는 역활을 한다고 했다. 하지만, 가슴에 와닿는 예시는 아니다. 진짜 가슴에 와닿으려면 프로그래밍적인 측면에서 접근해야만 한다. 그러기위해서 7번째 응용프로그램내에서의 이벤트를 추적해보면 훨씬더 가슴에 와닿을것이다.


그 구체적인 예시를 한번 추적해보자. 이번에도 Windows 프로그램을 기준으로 설명할것이다.


가장 간단한 구조인 윈도우폼 화면하나와 버튼두개가 있다고 가정하자. 버튼의 Caption (text) 은 각각 "A버튼", "B버튼" 이라고 하자. 이 구조에서 "A"버튼을 누르면 "B" 버튼의 캡션이 "A버튼"으로 바뀌고, "B버튼"을 누르면 "A버튼"으로 이름이 바뀐다고 가정해보자. 그것을 C# 이나 자바문법으로 처리하면 아래와 같다.

void btnA_onClick(sender id)
{
      string a = btnA.text;
      string b = btnB.text;
 
      btnA.text = b;
      btnB.text = a;
}
 
void btnB_onClick(sender id)
{
      string a = btnA.text;
      string b = btnB.text;
 
      btnA.text = a;
      btnB.text = b;
}


실제로 VS.NET 툴에서 만들어진 이벤트함수에 그냥 저렇게 입력만 하면 실제로 우리가 원하는 결과를 얻게된다. 그런데...위의 내용만으로 내가 원하는 프로그램을 구현하긴 했지만..먼가 이상하다. 그 이상함을 추적해보자.

  1. 사용자가 마우스를 클릭한다.
  2. OS 에서 마우스로 부터 클릭이벤트를 전달한다.
  3. 응용프로그램에서 어느객체에서 발생한 이벤트인지확인한다.
  4. 해당객체에 이벤트가 왔음을 알린다.
  5. 해당객체는 해당 이벤트에 대해 어떤메서드를 실행할지 정한다.
  6. 해당메서드 실행.


실제로 상단의 예제코딩은 1번과 6번을 제외한 모든 처리를 다 빠뜨리고 적어놓은 소스다. 정확히 표현하자면 2,3,4,5번에 대한 명확한 처리가 프로그램되어 있어야 한다.

물론, 실제로 버튼과 윈도우객체들은 이미 상기의 2,3,4,5번에 대한 모든 코딩이 되어 있다. 이중에서 우리가 주목해야 할것은 빨간색 부분인 2번과 4번이다. 저둘의 역활을 보면 전달 과 알림의 역활을 맡고 있다.


델리게이트의 사전적 의미를 생각해봐라... 대리자...위임자의 역활을 한다. 바로 2번과 4번이 우리가 공부하고 있는 델리게이트가 맡아서 처리하는 부분이다. 어떤가? 쉽지 않은가?? 이정도면 개념은 확실히 잡은거다.


델리게이트의 선언과 사용

우리는 개념을 잡고 있는 과정이라서 사실상 도움이 될만한 소스를 제시하지는 않는다. 다만, 개념을 조금 돕기위해 절차만을 정리하자면 이렇다.

  1. 내가 노출하고 싶은 이벤트를 발생시키고 싶은 객체에 델리게이트를 @Protocol 선언문을 이용해서 이벤트 메서드를 정의한다.
  2. 특정한 이벤트가 발생하였으므로, 이벤트 메서드를 델리게이트에게 시켜서(위임해서..) 노출한다.
  3. 이제 다른객체들은 이 객체에서 정의된 이벤트함수를 써서 이벤트발생시에 해당 함수를 실행한다.


델리게이트에 관한 마무리

자세한 소스나 구현방법은 스크랩자료들도 있고, 별도 강의자료들을 참조하기 바란다. 개념에 대한 이해가 된다면... 소스를 보는 눈도 달라지고 이해력도 훨씬 높아진다.


늘~ 얘기하지만, 어떻게 쓰느냐보다 더~ 중요한것은 왜? 쓰는냐가 더 중요하다. 델리게이트는 객체지향적인 언어에서는 어디서도 빠질수 없는 필수선언이며 기술이다. COM/COM+ 이모든것들은 델리게이트에 의해 자신의 기능을 다른객체에 노출한다. 어려운것은 없다. 다만 조금 헷갈릴뿐이다.