[App 개발] Cocoa Design Patterns (4)
본문
코코아의 모든 콜랙션 클래스는 계수기를 제공합니다. 이 패턴은 GOF의 반복기 패턴과 비슷합니다. 계수기는 객체의 집합을 훑어내고 각 객체에 어떤 일을 수행하는 방법을 제공합니다. 특정한 집합에 대하여 특수한 루프를 짜 주는 대신 어떤 종류의 객체의 집합이라도 동일한 방법으로 열거할 수 있습니다. 사용하는 방법은 집합에서 계수기 객체를 얻어낸 후 더 이상 객체가 나오지 않을 때까지 차례대로 다음 객체를 얻어냅니다. 임의의 집합 클래스 myCollection 을 사용하는 방법은 다음과 같습니다.
id instance;
id enumerator = [myCollection objectEnumerator];
while (instance = [enumerator nextObject]) {
// do something with instance
}
코드는 처음에 집합 클래스의 계수기를 얻어냅니다. 그 다음 계수기는 차례대로 그 다음 객체를 찾아냅니다. 계수기가 더 이상 찾을 객체가 없을 때에는 nil을 리턴하게 되고 루프는 멈추게 됩니다.
Foundation Kit의 모든 집합 클래스는 계수기를 지원합니다. 그 외의 어떤 객체들도 필요에 따라서 계수기를 지원하는 경우도 있습니다. 한 가지 다른 점은 계수기를 얻어내는 방법입니다. 왜냐하면 때에 따라서는 여러 가지 종류의 계수기가 있기 때문입니다. 예를 들어, NSArray 는 그 속의 모든 객체를 정방향으로 혹은 역방향으로 훑어내릴 수 있습니다. 이 두 방법은 따로 명확한 이름을 갖고 있습니다.
NSArray.h에서
-(NSEnumerator *)objectEnumerator;
-(NSEnumerator *)reverseObjectEnumerator;
만약 정렬되지 않은 집합이라면 장방향이나 역방향의 개념 자체가 없기 때문에 한 가지 계수기만 지원됩니다. 그 외에 NSDictionary같은 열거할 수 있는 여러 개의 집합을 정의할 수 있습니다. 두 개의 객체가 한 조를 이루는 사전의 경우 첫 번째 것은 key, 다른 것은 value가 됩니다. 여러분은 key를 중심으로, 혹은 value를 기준으로 계수를 할 수 있습니다.
NSDictionary.h에서
-(NSEnumerator *)keyEnumerator;
-(NSEnumerator *)objectEnumerator;
어쨌든 어떤 방법으로 계수기를 얻었든지 사용하는 방법은 동일합니다. 어떤 경우에는 다른 방향으로 사용하는 것이 유용한 경우가 있으며 계수기에서 리턴하는 모든 객체를 가지는 집합을 가지는 것이 유용할 때가 있습니다. 이렇게 하려면 간단히 계수기에게 리턴되는 모든 객체를 담고 있는 NSArray 를 요구하면 됩니다.
myArray = [myEnumerator allObjects];
Target/Action
만약에 사용자가 코코아의 유저 인터페이스를 조작하게 되면 그에 따른 특정한 메세지가 특정 객체에 발생합니다. 이것은 기존의 다른 응용 프레임웍들이 이벤트 루프를 가로채서 메세지 핸들러를 구현하는 것과는 다른 방법입니다. 코코아의 이러한 사용자의 행동에 대한 반응으로 직접 메세지를 전달하는 방식을 타겟/액션 이라고 합니다. 이 개념에서 타겟은 메세지를 받는 객체를 말하고, 액션은 전달되는 메세지를 뜻합니다.
액션은 버튼이 눌렸다든지 텍스트 필드의 편집이 끝났다든지 슬라이더가 움직였다든지 하는 행동으로 발생합니다. 각각의 인터페이스 객체들은 특정한 타겟과 액션을 가지고 있습니다. 일반적으로 한 가지의 인터페이스 객체는 특정한 액션만을 전달합니다. 이것은 어떤 인터페이스가 작동했을 때 어떤 일이 생겼는지 확인해볼 필요가 거의 없다는 뜻입니다. 어떤 경우 한 가지 액션이 한 개 이상의 객체에서 전달될 수도 있습니다. 예를 들어, 어떤 버튼은 응용 프로그램의 주 메뉴 항목과 똑같은 액션을 생성할 수도 있습니다. 이런 경우에는 어떤 것이 액션 메세지를 보냈는지 알고 싶을 것입니다. 그것은 쉽습니다. 왜냐하면 모든 액션에는 메세지를 보낸 사람이라는 전달인수가 있기 때문입니다.
타겟/액션을 이요하기 위해서는 두 가지를 해주어야 합니다. 첫 번째, 액션 메세지를 구현한 객체를 만듭니다. 액션 메세지는 다음과 같은 형태를 가집니다.
-(IBAction)someAction:(id)sender;
-someAction:이라는 이름은 여러분이 만들고자 하는 액션 메쏘드에 따라 달라집니다. 여러분의 액션 메쏘드를 구현하고 나면 인터페이스 빌더를 이용해서 인터페이스 객체와 메쏘드를 구현한 클래스의 인스턴스를 연결해 줍니다. 만들어준 인터페이스가 여러분의 응용 프로그램에서 사용하면 그 컨트롤이 활성화될 때 인터페이스 빌더에서 선택한 타겟으로 액션 메세지가 전달될 것입니다.
객체간 타겟/액션 연결은 프로그램적으로도 만드는 것이 가능합니다. 그 때 사용하는 코드가 여기 있습니다.
[myControl setAction:@selector(someAction:)];
[myControl setTarget:myTargetObject];
어떤 컨트롤의 타겟인지 액션인지를 살펴보기 위해서 -target 이나 -action 메쏘드를 이용해서 물어보면 됩니다. 여러분 자신의 컨트롤을 구현할 때 여러분은 어떻게 액션을 전달하는지를 알 필요가 없습니다 왜냐하면 NSControl 클래스는 액션 메세지를 전달할 때 사용하는 메쏘드를 구현하고 있기 때문입니다.
-(BOOL)sendAction:(SEL)theAction to:(id)theTarget;
여러분이 컨트롤 서브클래스에서 어떤 타겟이나 어떤 메세지를 보낼 때 이 메쏘드를 사용하면 됩니다.
최신글이 없습니다.
최신글이 없습니다.
댓글목록 0