사용자 도구

사이트 도구


language:cocoa:delegate

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.


language:cocoa:delegate [2024/04/23 22:44] (현재) – 만듦 - 바깥 편집 127.0.0.1
줄 1: 줄 1:
 +====== 델리게이트에 대해서 ======
  
 +일명 도우미 객체로서, 책에서는 이렇게 비유를 했다.
 +
 +로보캅의 경우, 사람의 서브클래스를 만들어 수십명의 외과의 공학자가 붙어서 사람을 전투머신으로 확장하여 로보캅이 완성되었다. -> 현재의 많은 프레임워크가 이 방식을 쓰고 있다.
 +
 +전격Z작전에서 마이클의 서브클래스를 만들어 총,자동차,로켓을 추가해서 모든 것을 재정의 하려고 했지만, 마이클에 많은 것을 알아야 장착이 가능했다. 그렇게 하는 것보다 키트를 만들어서, 도우미 객체로서 마이클에게 지급하고 마이클이 사용하도록 했다. 
 +
 +코코아에서는 재사용이 필요한 객체에 대해서, 상속 받아서 확장하는 것보다는\\
 +도우미 객체를 줘버려서 필요 없는 확장을 하지 않고도 기능 확장이 가능하도록 구성되어 있다.
 +
 +  C# 에도 있다는데, 잘 모르겠는데..
 +
 +다음과 같은 경우,
 +
 +  * 윈도우가 미니마이즈 되었을 때를 알고 싶다든지,
 +  * 윈도우가 종료되려고 할때,
 +  * 사이즈가 바뀌었을 때
 +
 +이런 인터페이스 상의 이벤트를 받아서 처리하고 싶을 때, \\
 +NSWindows 를 상속 받아서 새로운 NSMyNewWindow를 만들 것이 아니라 
 +
 +NSWindows에 선언던 델리게이트 함수를, 이벤트가 발생되었을때 자동으로 불리게 되는 함수들을\\
 +연결해서 쓸 수 있게 되면 더 간단하게 이벤트를 캐치해서 작성 할 수 있다.
 +
 +====== 델리게이트는 어떻게 설정하나? ======
 +
 +두 객체가 있다.
 +
 +  * A : 발생하는 이벤트를 처리하고 싶은 UI컨트롤, 윈도우나 버튼 등등
 +  * B : 기본 컨트롤 클래스, 프로그램의 이벤트를 처리하는 중심 바디 클래스 
 +
 +===== 인터페이스 빌드 상에서 =====
 +
 +스크린샷을 나중에 추가
 +
 +  - 발생하는 이벤트를 처리하고 싶은 UI컨트롤(A)에서 마우스 R-Click
 +  - Outlets 그룹에서 delegate 항목을 클릭한 상태로
 +  - Controller 클래스, 아니면 도우미 객체로서 이벤트를 받아서 처리해 줬으면 하는 클래스(B)
 +  - 로 마우스를 드래그한다.
 +
 +델리게이트 관계 설정은 이것으로 완료.
 +
 +===== 코딩으로 =====
 +
 +-> **이 방법 깔끔하게 안됨 . 뭔가 빠져 있는듯.**
 +
 +코딩으로 처리하기 위해서는, A 의 아웃렛 변수가 B 에 선언되어 있어야 한다.\\
 +또는,\\
 +B가 어디가에는 변수로 선언되어 있어야 한다.
 +
 +  * B(컨트롤러) 클래스의 init 또는 awakeFromNib 함수에서
 +
 +  [B setDeletgate:self]
 +
 +또는
 +
 +  [B setDelegate:someObject]
 +
 +로 코드를 추가한다.
 +
 +====== 델리게이트는 어떻게 쓰는건가? ======
 +
 +A Controller 에서 B window 의 델리게이트를 처리하고 싶다면,
 +
 +A에 B의 델리게이트 메소드를 자신의 메소드인냥 추가시키면 된다. 
 +
 +AppController 클래스가 NSWindow의 도우미객체로(델리게이트설정이) 되어 있고\\
 +NSWindow의 윈도우의 크기가 바뀔 때마다 크기를 강제로 설정해버리는 말도 안되는 예제를\\
 +구현한다고 했을때 
 +
 +<code objc>
 +// declare AppController
 +
 +#import <Cocoa/Cocoa.h>
 +
 +@interface AppController : NSObject 
 +{
 +    // IBOutlet NSWindow* mainWindow;
 +}
 +- (id) init;
 +// windowWillResize 는 NSWindow의 델리게이트 함수입니다
 +- (NSSize) windowWillResize:(NSWindow*)sender toSize:(NSSize)frameSize;
 +@end
 +
 +@implementation AppController
 +
 +- (id) init
 +{
 +    if( ![super init] ) return nil;
 +    // NSWindow의 델리게이트 기능을 수동을 설정
 +    //[mainWindow setDelegate:self];
 +    return self;
 +}
 +
 +// 윈도우가 리사이즈 될때마다 이 함수가 불려서 윈도우 크기를 강제로 (500,100)으로 설정해버립니다.
 +- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize
 +{
 +    NSSize _mySize;
 +    _mySize.width = 500.0;
 +    _mySize.height  = 100.0;
 +  
 +    NSLog( @"windowWillResize called" );
 +
 +    return _mySize;
 +}
 +
 +@end
 +</code>
 +
 +====== 델리게이트는 어떻게 동작하는 건가? ======
 +
 +NSObject에서 상속된 모든 클래스는 
 +
 +  - (BOOL) respondsToSelector:(SEL)aSelector
 +
 +이 메소드를 갖고 있다. 
 +
 +델리게이트용 클래스가 세팅 되어 있는 경우에는 (위 함수의 리턴값이 참이면) 델리게이트함수의 메소드를 부르고 없으면 원래의 메소드 내용을 실행하도록 되어 있다. (고 한다.. 정말인지 확인해보면 좋을 듯)
 +
 +델리게이트를 거쳐 가는지 확인해보고 싶다면,
 +
 +<code objc>
 +- (BOOL) respondsToSelector:(SEL)aSelector
 +{
 +    NSString *methodName = NSStringFromSelector(aSelector);
 +    NSLog( @"repondsToSelector:%@", methodName );
 +    return [super respondsToSelector:aSelector];
 +}
 +</code>
 +
 +로그를 남겨서 확인해보라.
 +
 +{{tag>cocoa}}