2011-10-07 3 views
11

저는 현재 Cocoa를 배우려고 노력하고 있습니다. 정확하게 이해한다면 잘 모르겠습니다 ... 및 컨트롤러에 대해 대표가 있습니다.Cocoa의 델리게이트는 무엇이며 왜 사용해야합니까?

처음에는 두 가지의 차이점은 무엇입니까? 때로는 클래스가 AppController이라고 불리는 코드를 볼 수 있습니다. 가끔은 - 같은 내용으로 - AppDelegate이 있습니다.

그래서 제대로 이해하면 대리자는 특정 이벤트가 발생할 때 메시지를받는 간단한 개체입니다. 예를 들어 내가 최소화 할 때마다, 지금

@implementation TryingAppDelegate 

@synthesize window; 
@synthesize winController; 

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    NSLog(@"-applicationDidFinishLaunching:"); 

    self.winController = [[WindowController alloc] init]; 
    [window setDelegate:winController]; 

    [self.winController release]; 
} 

@end 

그리고 다음 구현

@interface TryingAppDelegate : NSObject <NSApplicationDelegate> { 
    NSWindow *window; 
} 

@property (assign) IBOutlet NSWindow *window; 
@property (retain) WindowController *winController; 

@end 

: 이제

@interface WindowController : NSObject <NSWindowDelegate> 
@end 

@implementation WindowController 
- (void)windowDidMiniaturize:(NSNotification *)notification { 
    NSLog(@"-windowDidMiniaturize"); 
} 
@end 

, 나는 그것을 내 window의 대리자를 만들기 위해이 코드를 사용 window이면 -windowDidMiniaturize: 메시지가 WindowController에게 전송됩니다. 나는 그 권리가 있니?

그렇다면 보조 클래스를 추가로 다루는 것보다 NSWindow을 서브 클래스로 만들면 어떻습니까?

답변

7

대리인은 한 개체가 여러 개체를 조정할 때 특히 유용합니다. 예를 들어, NSWindowController 하위 클래스를 만들고이 클래스를 윈도우의 대리자로 만들 수 있습니다. 같은 창에는 창 컨트롤러를 위임자로 만들려는 다른 여러 요소 (예 : NSTextField)가 포함될 수 있습니다. 이렇게하면 윈도우와 그 컨트롤의 일부를 서브 클래스 할 필요가 없습니다. 개념적으로 속한 모든 코드를 동일한 클래스에 보관할 수 있습니다. 또한 델리게이트는 대개 모델 - 뷰 - 컨트롤러 개념의 컨트롤러 레벨에 속합니다. NSWindow을 하위 클래스 화하면 컨트롤러 유형 코드가 뷰 수준으로 이동합니다.

클래스는 임의의 수의 프로토콜을 채택 할 수 있으므로 <NSWindowDelegate, NSTextFieldDelegate>은 완벽하게 유효합니다. 그런 다음 개체를 원하는 수의 창과 텍스트 필드의 대리인으로 설정할 수 있습니다. NSTextField과 같은 클래스의 대표 메시지를 확인하려면 class reference을 확인하십시오. -delegate-setDelegate: 메서드는 대개 적절한 프로토콜을 나타냅니다. 우리의 경우 이것은 NSTextFieldDelegate입니다. 이전 버전의 Apple 프레임 워크에 추가 된 클래스의 경우 대리 클래스 메소드 ("클래스 메소드"및 "인스턴스 메소드"또는 "태스크"의 하위 섹션과 함께)에 대한 추가 섹션을 종종 제공합니다. 위임 프로토콜에 부합로 클래스를 선언하는 것은 그들에게 마술 개체에 전달하지 않습니다 - 당신이 명시 적으로 위임으로 설정해야합니다

@interface MyWindowController : NSWindowController <NSWindowDelegate, NSTextFieldDelegate> { 
    NSTextField *_someTextField; 
} 

@property (nonatomic, retain) IBOutlet NSTextField *someTextField; 

@end 


@implementation MyWindowController 

@synthesize someTextField = _someTextField; 

- (void)dealloc { 
    [_someTextField release]; 
    [super dealloc]; 
} 

- (void)windowDidLoad { 
    [super windowDidLoad]; 
    // When using a XIB/NIB, you can also set the File's Owner as the 
    // delegate of the window and the text field. 
    [[self window] setDelegate:self]; 
    [[self someTextField] setDelegate:self]; 
} 

- (void)windowDidMiniaturize:(NSNotification *)notification { 

} 

- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor { 
    return YES; 
} 

@end 

AppControllerAppDelegate는 동일한 유형의 단지 서로 다른 명명 규칙입니다 수업.

+0

고마워요! 내 컨트롤러는 어떤 프로토콜을 준수해야합니까? NSWindowDelegateProtocol을 사용할 때 NSTextField의 델리게이트로 만들 수 없을 것입니다. 그렇습니까? 그리고 그 요소들로부터 어떤 메시지를 받습니까? 아직도'windowDidMiniaturize' 등등? –

+0

(대리인) 프로토콜 및 예제에 대한 정보를 포함하도록 답변을 업데이트했습니다. – gcbrueckmann

관련 문제