2010년 2월 10일 수요일

iphone programming : Controller 작성

2.8. Controller 작성
앞에서 우리는 Interface Builder 를 완벽히 사용해서 화면 구성을 모두 끝냈고, Outlet 과 Action 이 모두 준비된 Controller 클래스도 생성했다.

프로그램을 완성하기 위해 남은 일은 단 하나, 바로 코드를 작성하는 일이다. 다시 말해서, 이제 정말로 Objective-C 프로그래밍 만이 남은 것이다.
Objective-C 언어에 대해서는 The Objective-C 2.0 Programming Language 와 같은 문서를 먼저 보는 것이 좋다. 이 문서는 그리 길지 않게 주요 사항들이 잘 요약되어 있다. 이 글이 작성되는 시점에서 2008 년 6월 9일 문서가 나와있다.
객 체 지향 개념에 대해서 보다 더 도움이 필요하거나, Objective-C 에서 어떻게 OOP 프로그래밍 개념을 구현하고 있는지에 대해서 정리하고 싶다면 Object-Oriented Programming with Objective-C 문서를 참조하면 큰 도움이 된다. A4 용지 분량으로 40페이지 문서지만, 개념적인 내용으로 이루어져 있고 당연히 영문 문서이기 때문에 OOP 경험이 없는 사람이라면 쉽게 읽혀지지는 않을 것이다.

다 시 언급하지만, Xcode 에서 제공하는 문서 보기 프로그램을 이용해서 여러가지 문서들을 쉽게 찾을 수 있으므로, 항상 애용하도록 하자. 문서 보기 프로그램의 개념은 마치 iTunes 에서 Pod Cast 를 이용하는 것과 비슷하며, 웹 문서로의 링크로 존재하는 부분들도 많이 있다.

이 문서에서는 상세하게 Objective-C 언어에 대해서 살펴보지는 않는다. 단지 간단한 프로그램을 작성하는데에 필요한 부분들만 빠르게 살펴보고, 직접 코드 작성에 이용해 보도록 하겠다. 이렇게 단순하게 몇가지를 살펴보면서 프로그램을 완성하면 전체적인 윤곽을 잡는데에 도움이 될 것이다. 또한, 반드시 각자 Objective-C 언어에 대해서 별도의 문서를 살펴보기 바란다. 다행히, Objective-C 언어는 그렇게 복잡한 문법을 가진 언어가 아니다.

이제 Xcode 의 Workspace 에서 MyHelloViewController.m 파일을 에디터 창에서 열고 살펴보자.
아마도 다음과 같은 형태로 코드가 작성되어 있을 것이다.


#import "MyHelloViewController.h"

@implementation MyHelloViewController
- (IBAction)changeGreeting:(id)sender {
    
}
@end


C언어 비슷하지만 상당히 낮선 형태의 코드가 보인다. #import 구문은 눈치를 보아하니 #include 와 같은 것으로 보이고, 실제로 그렇다.
다 시 한번 말하는데, Objective-C 는 C 언어의 모든 구문을 사용할 수 있다. C 언어 위에 객체지향 관련 사항만 추가되어 확장된 형태다. #include 역시 사용 가능하지만, Objective-C 에서는 #import 를 주로 사용한다. 그 이유는, 중복되는 include 를 컴파일러가 알아서 막아주기 때문이다. 따라서 헤더 파일에 쓸데 없는 중복 회피용 전처리기 구문을 넣지 않아도 된다.

또 한가지 요상한 것이 보이는데, 이른바 골뱅이 문자(@)의 사용이다. @ 문자는 Objective-C 에서만 사용되는 지시문을 사용할 때 함께 사용되는데, 위에서는 @implementation 과 @end 가 보인다.

제일 헷갈리는 것이 
changeGreeting: 이 선언되어 있는 모습이다. 여기서 이것을 자세하게 말하지는 않겠지만, C 언어의 함수 정의로 해석해 보자면
  IBAction changeGreeting( id sender ) { ... }

와 같다고 보면 된다. 왜 이렇게 이상한 형태로 되어있는지, Objective-C 언어 문법을 공부하다 보면 자연스럽게 알게 될 것이다. 우리는 일단 넘어가도록 하자.

C 언어 식으로 말하자면, 버튼을 클릭하면 changeGreeting: 함수가 호출되도록 되어 있다. 그러면, 일단 간단하게 버튼을 클릭하면 화면에 어떤 변화가 일어나도록 코드를 작성해 보자.

우리가 처음 하려던 것은, 버튼을 클릭하면 화면 중간에 있는 라벨의 문구가 변경되도록 만드는 것이었다. 일단 시험을 해보기 위해, 버튼 클릭시 라벨의 문구가 영구적으로 변경되도록 다음과 같이 작성해보자.

- (IBAction)changeGreeting:(id)sender {
    label.text = @"잘가요!";
}

label 의 text 속성 값을 문자열 대입에 의해 변경한다는 것으로 이해한다면 쉽게 읽을 수 있을 것이다. 사실 이것은 Objective-C 방식의 해석으로는 틀린 것이지만, C 언어 프로그래머가 보기에는 마찬가지다.
한 가지 이상한 것은 문자열 따옴표 앞에 @ 문자가 또 다시 나타난다는 점이다. @ 문자가 앞에 있는 문자열은 C 언어의 문자열과는 다르다. 이것은 Objectiv-C 언어에서 사용하는, 문자열 객체라는것 정도로만 이해하고 넘어가도록 하자.

그리고, 다음과 같이 새로운 메소드를 하나 추가하자. 이것은 프로그램이 종료될 때 메모리를 정리하기 위한 구문이다. release 의 자세한 의미는 나중에 살펴보기로 하자.

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

현재까지 작성된 MyHelloViewController.m 소스의 전체 코드는 다음과 같다.

#import "MyHelloViewController.h"


@implementation MyHelloViewController

- (IBAction)changeGreeting:(id)sender {
    label.text = @"잘가요!";
}

- (void)dealloc {
    [textField release];
    [label release];
    [super dealloc];
}
@end

소스 코드를 저장하고서 Build & Run 으로 실행해 보자. 만일 소스코드에 오류가 있다면 오류가 있는 위치에 에러 표시가 나타나서 쉽게 수정할 수 있다. 의도적으로 소스 코드에 에러를 만들어서 Workspace 가 어떤 식으로 에러 표시를 하는지 보는것도 좋다.


프로그램을 실행한 후, 버튼을 클릭하면 라벨의 문구가 소스 코드에서 지정한 대로 변경된다. 물론, 원래 상태로 돌아오도록 하는 기능은 없기 때문에, 다시 초기상태로 돌아가는 방법은 현재로서는 프로그램을 종료하고 다시 실행하는 것 뿐이다. 하지만, 약간만 더 작성하면 우리의 MyHello 프로그램은 원하는 모습대로 동작하는 프로그램으로 완성될 것이다.


현재 버튼을 클릭하면(다르게 말하면 '터치'하면) 라벨의 내용이 변경되도록 코드를 작성해 보았다. 이제는 Text Field 에 입력한 내용으로 라벨의 내용을 변경하도록 작성해 보자. 기본 기능에 의해 텍스트 필드에 문자열을 입력하는 것 까지는 가능하지만, 현재 문자열 입력을 종료하고 키보드를 다시 닫는 동작이 이루어지지 않는 상태다. 먼저 키보드의 Enter 키 처리를 추가하도록 하자.

이것은 조금 성가신 작업이 필요한데, 다시 MyHelloViewcontroller.xib 를 더블 클릭하여 Interface Builder 를 실행해야 한다. 왜냐하면, 앞서 Interface Builder 에서 딱 하나 해주지 않고 미뤄둔 작업이 있기 때문이다.

Interface Builder 에서, View 화면에 있는 텍스트 필드를 마우스 우측 클릭으로 connection 창을 열고서 delegate 연결을 File's Owner 와 연결해준다. 이제는 아래 그림을 보면 다들 쉽게 이해할 수 있을 것이다.

이제 대충 짐작이 가지 않는가? textField 의 delegate 메시지를 우리가 작성중인 MyHelloViewController 에서 받아서 처리하겠다는 것을 명시하는 것이다. 이제 textField 에서 발생하는 어떤 종류의 사건들은 위임 메시지가 되어 우리가 작성하는 컨트롤러 클래스로 전달되게 된다. 그 메시지들 중 처리할 수 있는 것들만 메소드를 만들어서 처리하면 된다.

XIB 파일이 수정되었으면 어떻게 해야 하는지 기억나는가? 딱 한번 해보았기 때문에 많은 사람들이 기억하지 못할 지도 모르겠다. Interface Builder 에서 내용 수정이 일어났기 때문에, File's Owner 아이콘이 선택된 상태에서 메뉴의 'Write Class Files...' 을 선택하여 다시 MyHelloViewController 헤더 파일과 소스 파일을 저장해주어야 한다. 그리고 필히, 저장 확인시 Merge 를 선택해서 지금 작업중인 내용들을 보존해 주기 바란다.(Merge 수행 시 실행되는 소스 Merge 프로그램이 좀 원시적인 것은 아쉽다)

저장한 소스를 확인해 보면 MyHelloViewController.h 헤더 파일에 한가지 내용이 추가된것을 볼 수 있다.

@interface MyViewController : UIViewController 
<UITextFieldDelegate> { ... }

이제는 키보드에 Enter 키 입력이 발생하면 텍스트 필드의 해당 동작에 대한 위임(delegate) 메시지가 발생해서 컨트롤러로 전달되게 되었다. 현재는 이 위임 메시지를 처리하는 곳이 없다. 이것을 처리하려면 다음과 같이 
textFieldShouldReturn: 메소드를 만들어주면 된다. 이 메소드 역시 MyHelloViewController.m 코드에 추가하면 된다.
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
    if( theTextField == textField ){
        [textField resignFirstResponder];
    }
    return YES;
}

메소드를 선언하는 형태가 다소 복잡해 보이지만, 지금은 theTextFieldShouldReturn: 이름만 기억하고 넘어가도록 하자.
메소드 안에 있는 if() 문은 지금 이 프로그램에서는 필요 없다. 왜냐하면 if() 문의 조건문을 보면 알겠지만, Enter 키가 입력된 텍스트 필드가 구체적으로 어떤 것인지를 확인해서 
resignFirstResponder: 메 소드를 호출해주고 있기 때문이다. 현재 사용된 텍스트 필드 아이템 객체는 단 하나뿐이므로, 지금 구분하는 것은 사실상 의미가 없다. 하지만 두개 이상의 텍스트 필드가 사용되는 프로그램을 작성한다면, 현재 보여주고 있는 if 문과 같은 처리가 꼭 필요할 것이므로, 기억해 두는 것이 좋다.
resignFirstResponder: 라는 것의 의미는, 현재 텍스트 필드가 키보드를 보여주면서 모든 입력을 우선적으로 받아서 처리하는 First Responder 상태가 되어 있지만, 이제 그것을 포기하고 넘겨주겠다는 것을 의미한다. 따라서 textField 안에 있는 resignFirstResponder: 메소드 안에는 그에 해당하는 처리를 하는 코드가 있을 것이다. 그리고 우리는 YES 를 리턴한다.

이것으로 텍스트 필드에 열려있던 키보드는 다시 닫혀지게 된다. 여기까지 작성한 후, 다시 프로그램을 build 하고 실행해서 시뮬레이터를 실행해 보도록 하자. 이번에는 텍스트 필드에 문자를 입력한 후 엔터키를 눌러서 입력을 종료할 수 있게 되었다.

자, 이제 텍스트 입력이 자유롭게 되었으므로, 버튼의 동작을 원래 목적했던 것으로 완성하자.
Workspace 에서 에디터를 열고 앞서 작성했던 
changeGreeting: 메소드의 내용을 다음과 같이 수정해 보도록 한다.
- (IBAction)changeGreeting:(id)sender {
    NSString *nameString = textField.text;

    NSString *greeting = [[NSString alloc] initWithFormat:@"안녕하세요 %@!", nameString];

    label.text = greeting;
    [greeting release];
}

NSString 은 Cocoa Foundation 에서 정의된 문자열 객체로서, Mac 프로그래밍에서 모든 문자열은 이것으로 사용한다고 말해도 틀리지 않다. 메소드 첫 줄에서 textField 의 문자열을 nameString 으로 가져오고 있다. '가져온다'는 표현은 상당히 애매한 표현이다. 나중에 NSString 에 대한 각종 정보를 The Objective-C 2.0 Programming Language 문서나 String Programming Guide for Cocoa 문서 등을 참조하여 확인해 보기를 권한다.
Cocoa Foundation Class 들의 이름은 전부 대문자 NS 로 시작한다. 당연히, 이것은 NeXT Step 의 머릿글자다. 새로 만들어진 iPhone 용 Foundation 들의 이름은 더 이상 NS 로 시작하지 않지만, 기본적인 Cocoa Foundation 들의 모든 Class 는 이 규칙을 지킨 채 남아있다.

initWithFormat: 메소드는 마치 printf 처럼 문자열에 의해 지정된 형식으로 새로운 문자열을 만들기 위해 사용된다. 이렇게 해서 greeting 이라는 이름의 새로운 문자열 객체를 alloc 으로 만들고 있다. 새로 만들어진 문자열에 의해 Label 의 내용을 수정한 다음, greeting 은 release 를 호출해 주어야 한다.

이제 프로그램을 Build 해서 시뮬레이터로 직접 테스트 해 보자. 임의의 문자열을 입력한 후 버튼을 클릭하면 라벨의 문구 내용이 변경된다. 우리의 첫 번째 iPhone Application 이 완성된 듯 하다.


여기에 약간의 코드를 더 추가해서 프로그램을 완결짓도록 하자.
다음은 일부 코드가 추가된 MyHelloViewcontroller.m/h 소스 코드의 전체 내용이다.
#import <UIKit/UIKit.h>

@interface MyViewController : UIViewController <UITextFieldDelegate> {
    IBOutlet UITextField *textField;
    IBOutlet UILabel *label;
    
NSString *string;
}

- (IBAction)changeGreeting:(id)sender;

@end

#import "MyViewController.h"

@implementation MyViewController

- (IBAction)changeGreeting:(id)sender {
    
string = textField.text;

    NSString *nameString = string;
    
if ([nameString length] == 0)  nameString = @"이름은?";

    NSString *greeting = [[NSString alloc] initWithFormat:@"안녕하세요 %@!", nameString];

    label.text = greeting;
    [greeting release];
}

- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
    if (theTextField == textField) {
        [textField resignFirstResponder];
    }
    return YES;
}

- (void)dealloc {
    [textField release];
    [label release];
    
[string release];
    [super dealloc];
}
@end

그냥 사용해도 되는 textField.text 의 내용을 왜 굳이 string 이라는 이름의 인스턴스 변수를 만들어서 한번 더 거치는지, 그냥 코드를 보면 잘 이해가 되지는 않는다. 이것은 Apple 의 Tutorial 에서 하나의 예로서 보여주고 있는 방법으로서, 가장 단순한 방식으로 MVC 패턴의 Model 을 구현하여 다루고 있는 방법이다. 일반적으로 컨트롤러는 응용 프로그램의 정보를 자신의 모델 객체에서 관리하며, UI 아이템에 데이터를 저장해서 사용하지 않아야 한다. 일단 지금은 이정도로만 넘어가도록 하자. 이렇게 새로 추가된 string 객체 때문에 dealloc 메소드 안에서 release 처리가 추가되었다.

참고로 덧붙여 말하자면, 본 프로그램은 Tutorial 문서에 기반하고 있지만 
@property, @synthesize 구문은 사용하지 않고 작성되었다. 궁금하다면 Tutorial 문서에 있는 원본 소스코드를 참조하여 비교해 보기 바란다. 이 두 가지 구문에 대한 것은 조금 뒤에서 Objective-C 언어 문법을 정리하면서 다루도록 하겠다.


자, 이렇게 iPhone/iPod Touch 용 Application 을 완성했다.
하지만, 한가지 좀 더 재미있는 것을 추가해 보자. (완성이라고 말하고서는 자꾸 추가해서 미안하다. 하하핫.) 이것은 Tutorial 문서에서는 다루지 않는 것이지만, 간단한 작업이고 결과는 효과적이다.

시뮬레이터를 좌/우로 90도 돌려보자. 방향을 바꾸더라고 아무런 일도 일어나지 않는다. 당연히, 방향 전환에 대해서 우리의 프로그램이 처리하지 않고 있기 때문이다.

이제 다음과 같은 메소드를 컨트롤러에 추가하라.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations.
    return YES;
}

shouldAutorotateToInterfaceOrientation: 메시지는 iPhone 의 자세가 90도 단위로 변경되면 View 의 컨트롤러에게 전달된다. 컨트롤러에서 이 메시지를 받아서 YES 를 return 하면, View 는 자신의 형태를 현재 위치에 맞게 '변신' 한다. 당연히, View 위에 뿌리를 내리고 살림을 차리고 있던 모든 녀석들도 덩달아 돌아가거나 크기를 변경하게 된다.

아래 그림처럼 시뮬레이터를 90도 기울여보자.

이 그림을 보면, 가장 위에 있는 textField 는 변경된 가로 길이에 맞게 자신의 길이를 조절했다. 그러나, 아마 여러분의 프로그램은 그렇지 못할 것이다. 대부분 가로 길이가 고정된 채로 남아있고, 오른쪽에 빈 공간이 생겼으리라 예상된다.
왜 그럴까? 그것은 필자가 Interface Builder 에서 textField 를 화면에 배치할 때 뭔가 해주었기 때문이다.

위에 그림에서 텍스트 필드는 크기를 화면에 맞게 조정했지만, 라벨과 버튼은 고정된 자리를 지키고 있기 때문에 중앙에서 벗어난 자리에 있게 된다. 별로 보기 좋지 않으므로 이것도 항상 가운데 정렬을 유지하도록 수정하자. 수정은 당연히 Interface Builder 에서 해주면 된다.

아주 간단하다. 배치되어 있는 버튼을 선택하고 아래 그림처럼 Size 속성 탭을 보자. 이 그림에서 주목할 것은 가운데 영역의 
Autosizing 부분이다. 현재 버튼의 자동 위치,크기 설정을 붉은색 선을 클릭해서 켜고 끄는 것으로 모두 지정할 수 있다. 즉, 아래 그림처럼 설정하면 상단으로부터의 거리만 고정된 채, 화면 좌/우측과의 거리는 자동으로 같은 비율을 유지하게 된다. 같은 방법으로 Label 아이템의 Autosizing 설정도 변경해 보도록 하자.

이렇게 아이템의 설정을 변경하고, XIB 파일을 저장한다. 단, 소스 코드에 영향을 미치는 수정 사항이 아니므로, Write Class Files... 는 해줄 필요 없다.

이제 Xcode 에서 프로젝트를 다시 Build 한 후에 실행해서 그 결과를 확인해 보자. 어떤가? 복잡한 화면 처리도 View 에서 알아서 처리해 주기 때문에, Application 프로그래머는 불필요한 시간 낭비를 하지 않아도 된다. 이제 우리의 프로그램은 화면을 옆으로 돌려도 보기 좋은 레이아웃을 유지한다.

당연히, 화면이 옆으로 변경되었어도 키보드 입력 등 모든 동작은 정상적으로 이루어진다.

이로서 (이번엔 진짜로) 우리의 첫 번째 iPhone Application 제작을 끝마칠 때가 왔다. 모두 iPhone 프로그래밍의 매력을 충분히 느낄 수 있었으리라 생각한다. 이 프로그램을 각자 살펴보고 원하는대로 수정하면서 Xcode 와 Interface Builder 사용에 익숙해지기 바란다. 그리고 궁금한 점은 Apple 에서 제공하는 각종 문서를 검색하면 빠르게 적응할 수 있을 것이다.

특히, Objective-C 언어에 대한 사항은 위에서 계속 언급한 별도의 문서들을 따로 참조하는 것이 좋다. 지금까지 우리는 Objective-C 문법에 대한 사항은 자세히 살펴보지 않았는데, 이제 언어 문법과 개념적인 내용에 대해 다음에 간단하게 정리하고, 다음 프로젝트로 진행하는 것이 좋으리라 생각된다.

내 생각이지만, C++ 언어보다 훨씬 쉽다.

iphone programming : view 구성하기

2.7. IB 에서 View 구성하기

지금까지 우리는 정해진 템플릿에 의해 Xcode 가 기본으로 생성해준 코드들과 XIB 내용을 살펴보고, 프로그램이 시작되는 동작을 살짝 엿보았다.

이제 Interface Builder 에서 새로운 UI 를 작성해 보자. 처음에는 하나의 Label 아이템만을 사용했지만, 이제는 3가지 아이템을 View 창 위로 끌어다 놓고, 위치와 속성을 조절할 것이다.

우리가 사용해볼 아이템은 Text Field, Label, 그리고 Round Rect Button 이 되겠다. 필자는 아래 그림처럼 세 아이템을 나열하고, 크기와 위치를 조정한 후, 몇가지 속성을 수정하였다. 기본적으로 이것은 Apple 의 iPhone Application Tutorial 문서에서 보여주는 예제와 같다.


여러분은 각자 원하는대로 조금씩 그 형태를 다르게 해도 무방하다. 참고로, 위 그림에서 버튼의 색이 파랗게 보이는 이유는 필자가 버튼 속성에서 Highlighted 항목을 체크 표시로 변경했기 때문이다.

각각의 UI 아이템을 배치하고 속성을 조절하는 것에 대해서 더 이상 설명할 필요는 없을 것으로 생각된다. 대부분 이런 식으로 UI 를 제작하는 프로그래밍 툴을 한두가지 사용해 본 경험이 있을 것이고, 근본적으로는 이런 식의 UI 디자인 개발 도구 자체가 직관적으로 사용할 수 있도록 되어 있기 때문이다.
게다가, 이건 다른 회사도 아닌 Apple 에서 만든 (NeXT STEP 부터의 역사를 가진) 개발 도구란 말이다. 직관적으로 빠르게 학습 가능한 UI 로는 세계 최고의 회사가 만든 도구라는 것을 상기하자.


이제, 우리가 원하는 프로그램의 외형은 일단 완성되었다. 성급하지만, 이 상태에서 Interface Builder 의 XIB 파일을 저장하고, Xcode 로 전환한 후 Build & Run 을 수행해 보자. 시뮬레이터가 동작하면서 지금까지 작성한 결과를 보여준다.

인터페이스 빌더로 작성한대로 모든 것이 보여질 것이다. 물론, 버튼을 눌러도 아무 동작도 하지 않는다. 그렇다면, 이번에는 맨 위에 배치한 텍스트 필드를 클릭해보자.
텍스트 필드에 클릭을 했다는 것은 당연히 사용자가 원하는 문자를 입력하려는 것이다. 따라서, iPhone OS 는 사용자가 문자를 입력할 수 있도록 키보드를 제공한다. 우리는 텍스트 필드를 화면에 배치하면서 여기에 사용할 키보드 형태를 별도로 변경하지 않았기 때문에, 화면에 기본형 키보드가 나타날 것이다. 만일 시뮬레이터 환경 설정에서 다국어 입력 지원을 설정해 놓았다면, 키보드의 지구본 키를 클릭히여 한국어를 비롯한 다른 언어들의 키보드로 전환할 수도 있다.

키보드 버튼들을 클릭하면, 입력된 문자가 텍스트 필드에 입력된다. 그런데, Enter 키를 클릭해도 아무런 변화가 없다. 키보드 입력 상태를 벗어나기 위해서 화면 밖 부분을 클릭하거나 다른 시도를 아무리 해봐도, 키보드를 다시 닫고 처음 화면으로 돌아갈 수 없을 것이다!

그 이유는, 필요한 키보드 입력 처리 코드를 작성하지 않았기 때문이다. Enter 키 입력에 대한 처리를 추가하면 의도한대로 다시 키보드를 닫을 수가 있게 될 것이다. 하지만 현재 상태로는 Home 버튼을 눌러서 프로그램을 종료한 후 다시 실행하는 방법 밖에는 없다. 실망스럽겠지만, 온전한 동작을 하도록 코드를 구성하는 것은 조금 후에 작업하도록 하겠다.

그러면 시뮬레이터를 닫아서 구경은 그만두고, 다시 Interface Builder 로 돌아가 보도록 하자.


자, 다시 현재 상황을 보자.
IB 에서 구성한 사용자 인터페이스는 시뮬레이터에서 확인해 본 대로, 정확히 눈에 보이는 것 그대로 구성되어 있다. 하지만 서로 연결되어 동작하는 것은 하나도 없는 상태다.

각 UI 아이템들이 서로 유기적인 동작을 이루기 위해서는, 먼저 
'연결'이 되어야 한다. 따라서, 구체적인 코드를 작성하기 전해 해야 하는 작업은 이 아이템들을 연결하는 일이다.
구슬이 서말 이라도 꿰어야 보배이듯이, View 위에 아이템이 서말이라도 연결해야 보배다.

사실, 연결 작업 그 자체는 Objective-C 소스 코드에 코딩을 하는 작업이다. 그래서 지금 Interface Builder 를 닫고 Xocde Workspace 상에서 작업을 해도 된다. 실제 Apple 의 Tutorial 문서에서는 소스 코드에서 작업하는 것을 기본으로 설명하고 있다.

하지만, 여기에는 선택이 가능하다. 즉, 작업자의 기호에 따라 Workspace 에서 직접 소스코드를 작성해도 되며, 같은 작업을 Interface Builder 에서 해도 된다. 전적으로 이것은 프로그래머가 원하는 바에 달렸다.

이 문서에서는 이미 말한대로, Interface Builder 에서 작업하는 것을 중심으로 설명해 나가기로 한다. 작업 결과를 보면 자연스럽게 소스 코드를 어떻게 고치면 되는지 알 수 있고, 따라서 처음부터 소스코드에서 작업하는 것 보다는 IB 에서 하는 것이 기억하기 쉽다.



그러면, 짝짓기를 해보자.

Interface Builder 에서 작업했던 MyHellloViewController.xib 를 열고, 여기서 File's Owner 아이콘을 선택하면 Identity 창에 Class Actions 칸과 Class Outlets 창 등이 있는 것을 볼 수 있을 것이다.

지금부터 잘 보기 바란다.

먼저, 하나의 
Action 을 지정하자.
액션은 말 그대로, 어떤 동작을 할 것인지에 관한 것이다.
MyHelloViewController 에 Action 을 추가한다는 것은, 다른 외부 객체가 지금 우리가 생성하고 있는 이 객체로 어떤 동작(Action)을 요구할 수 있도록 연결점을 만든다는 뜻이다.

도데체 어떤 녀석이 이 컨트롤러에게 동작을 요구할 것인가? View 에서 이 Controller 에게 동작을 요구할 녀석이 누구일지 생각해 보자.
현재 View 위에 배치된 세 개의 아이템 중, '버튼' 만이 그런 요구를 할 녀석이다. 사용자가 버튼을 클릭하면 버튼은 controller 에게 '야, 나 눌렸어! 이제 알아서 해!" 라고 Action 을 요구해야 한다.

따라서, 우리의 MyHelloViewController 에는 버튼이 Action 을 요구할 수 있는 문이 있어야 한다.
그 작업이 바로 컨트롤러에 Action 을 추가하는 작업이다.

Interface Builder 상에서 Action 추가는, Identity 창에서 Class Actions 항목 아래쪽에 있는 플러스[+] 버튼을 누른 후 왼쪽 칸에 원하는 이름을 기입하면 된다. 지금 type 은 신경쓰지 말고 id 로 남겨둔다.

Action 의 이름은 콜론(:)으로 끝나는 문자열이다. 왜냐하면, 사실 Action 이라는 것의 개념은 다른 클래스에서 호출하는 메소드와 같다. 즉, 다른 누군가가 호출할 함수 하나를 만든 셈이다.




우리의 프로그램에서는 Action 은 하나로 충분하다. 이제, Identity 창의 아래쪽에서 
Outlet 을 추가하도록 한다.
Outlet 은 Action 과는 반대다.
Outlet 은, 컨트롤러 안에서 다른 객체를 지정해서 사용할 명칭을 의미한다.
다시 말해서, 미국에 있는 어떤 도시를 우리나라 사람이 '나성' 이라고 부르는 행위와 같다. 여기서 
'나성'이라는 단어는 우리나라가 사용하는 하나의 Outlet 이 되며, 이 Outlet 은 미국의 LA 와 연결된다.

비유가 좀 괴상한가? 말로 길게 설명하는 것이 오히려 도움이 안될지도 모르겠다.
일 단, 작업 진행을 계속 살펴보도록 하자. 그림에서 보는 것과 같이 Identity 창에서 두 개의 Outlet 을 추가하는데, label 이라는 이름의 아웃렛과 textField 라는 이름의 아웃렛이다. 이름은 아주 단순하게 지었다.
그리고 각 아웃렛의 우측 열에는 각 아웃렛이 연결될 Object 가 어떤 형태인지 그 클래스를 명시해 준다. 이렇게 위 그림과 같이 추가했다면 일단 Outlet 생성 작업은 끝이다.

다시 정리해보자. File's Owner 에 두 개의 Outlet 을 추가했다. 이 뜻은, MyHelloViewController 객체에서 label 이라는 이름으로 외부에 어떤 UILabel 형태의 객체를 참조해서 사용하겠다는 뜻이고, textField 라는 이름으로 외부의 어떤 UITextField 형태의 객체를 참조해서 사용하겠다는 뜻이다.

사용되어질 Action 도 만들고, 사용하겠다고 Outlet 까지 만들었는데, 누가 Action 을 사용해 줄 것이며, 누구의 객체를 Outlet 을 통해서 사용하겠다는 말인가?
컨트롤러 객체 안에서 혼자 주장해봤자 아무 소용 없다. 실제 우리가 목적으로 하는 형태로 실제 연결을 해 주면 진짜로 구슬 서 말이 꿰어서 보배가 된다.

IB 에서 연결 작업은 흥미롭다.
먼저, File's Owner 아이콘을 마우스 오른쪽 클릭 - 필자같이 아직도 원 버튼 마우스 사용자라면 Ctrl-클릭 - 을 한다. 그러면 반 투명으로 시커먼 목록 창이 하나 나타난다.

여기에는 컨트롤러 객체가 가지고 있는 아웃렛과 액션 등의 목록이 연결 상태와 함께 나타난다. 그중 우리가 앞에서 등록한 label 이라는 이름의 아웃렛이 보이는데, 여기서 우측에 있는 작은 동그라미를 클릭한 후 화면 밖으로 쭉 드래깅 해 보자!

파란 직선이 그어지는데, 이 선을 View 창에서 실제 Label 아이템 위에다가 놓고 마우스 버튼을 놓으면 해당 아웃렛과 지정한 라벨 객체의 연결이 완성된다. 아주 직관적인 작업이 아닐 수 없다.
설명이 조금 와닿지 않는다면, 아래 그림을 참조해서 잘 보기 바란다.


같은 방법으로 TextField 아웃렛도 연결해 보자. 잘 살펴보면, view 라는 이름의 아웃렛이 이미 View 와 연결되어서 등록되어 있는 것을 볼 수 있다. 이렇게 연결 작업이 끝난 label 아웃렛과 textField 아웃렛은 Controller 코드 안에서 원하는 목적에 맞게 사용할 수 있을 것이다.

이제 Outlet 을 준비하는 과정은 끝났다. 이제 남은 Action 의 연결을 완성하는 것으로 준비 과정을 마무리 짓기로 하자. Action 의 연결 작업도 Outlet 과 별로 다른점은 없다.

앞서 했던 방식대로, File's Owner 아이콘에서 마우스 우측 클릭으로 연결상태 창을 연 후에 이번에는 changeGreeting: 아웃렛의 우측 동그라미를 버튼과 연결한다.버튼 위레서 바우를 떼면, 버튼의 어떤 동작과 해당 Action 을 연결할 것인지 샌택하는 또 하나의 반투명 팝업 창이 나타난다. 여기서 가장 일반적으로 버튼 동작에 사용하는 
Touch Up Inside 와 연결하면 된다.

참고로, 반대로 작업할 수도 있다. View 의 버튼 아이템에서 마우스 우측 클릭을 하면 마찬가지로 오른쪽에 동그라미를 달고 있는 항목들로 이루어진 반투명 창이 나타나는데, 여기서 Touch Up Inside 의 오른쪽에 있는 동그라미에서 마우스를 클릭한 후 File's Owner 아이콘으로 끌고가면 된다. 마우스를 놓으면 어느 Action 과 연결할 것인지를 선택하는 창이 나타나는데, 우리가 만들어놓은 Action 은 하나 뿐이므로, changeGreetion: 하나만 선택할 수 있는 작은 창으로 나타날 것이다. 이것을 선택해 주면 역시 Action 의 연결 작업이 완결된다.


이렇게 GUI 객체간의 연결 작업을 마우스로 선을 그어 연결하는 방식은 기본적으로 NeXT STEP 의 프로그래밍 환경에서 하던 것과 별 차이가 없다. 현재의 Xcode 는 NeXT STEP 의 개발 환경이 아직도 진화중인 모습에 불과하다고 말할 수 있다.

자, 이제 정신을 차려보자. 어느덧 Interface Builder 에서 구성할 수 있는 모든 작업이 다 끝난 셈이다. 지금 우리가 뭘 했는지 다시 한마디로 말해보자면, Interface Builder 를 이용해서 View 를 구성했고, 이와 연결된 Controller 의 기본 형태를 작성했다.
MVC 중에서 View 와 Controller 일부를 작성한 셈이다.

Controller 를 작성했다고?
그렇다. 분명히 화면에 버튼과 라벨을 배치한 View 와 연결된, 그것의 컨트롤러인 MyHelloViewController 에 아웃렛과 액션을 정의해서 연결을 만들었다. 구체적인 동작은 없지만 Controller 의 기본 틀은 모두 작성한 것이다.

하지만, 당연히 Controller 라는 것은 Objective-C 소스 코드이어야 한다. 그래야 구체적인 동작을 작성해서 프로그램을 완성할 수 있으니까.
그렇다면, 지금까지 Interface Builder 에서 작성한 내용도 소스 코드로 작성되어 있어야 한다. 물론, 처음 템플릿에 의해 MyHelloViewController.m 과 MyHelloViewController.h 헤더 파일이 작성되어 있다. 그러나, 우리가 지금 추가로 Interface Builder 에서 작업한 내용은 아직 소스 코드에 반영되지 않은 상태다.

그래서, Outlet 과 Action 작성, 연결 등을 한 내용을 컨트롤러 소스 코드에 반영해주는 작업이 필요하다.
아래 그림처럼 Interface Builder 파일 메뉴를 보자. 여기서 
Write Class Files... 항목을 선택하면 작업한 내용을 소스 코드로 작성해서 저장하게 된다.(잠깐. 작성된 View 를 저장하기 위해서는 XIB 파일을 저장해야 하는 것은 당연하다. 혼동하지 말자.)



저장하는 파일의 이름과 위치, 그리고 헤더 파일을 함께 저장할지 등을 묻는 대화창이 다음 그림과 같이 나타난다. 일반적으로 별도의 변경 없이 그대로 Save 버튼을 클릭해서 진행하면 된다. 앞서 언급한 바와 같이, MyHelloViewController.m 과 .h 는 템플릿에 의해 이미 작성되어 있기 때문에, 저장할 위치에 같은 이름의 파일이 보일 것이다.


같은 이름의 파일이 이미 있으므로, Save 를 진행하면 당연히 다음과 같은 창이 나타난다. 소스 머지를 선택하는 것이 일반적인 선택이 될 것이다. 혹은 기존 소스를 새로운 소스로 완전히 대체할 수도 있다. 상황에 맞게 선택하면 된다.




Interface Builder 안에서 할 수 있는 일들은 다 한것 같다. 이제 Xcode 의 Workspace 로 돌아와서, 방금 저장한 MyHelloViewController.m 과 MyHelloViewController.h 파일의 내용을 확인해 보자. 분명히 새로 추가된 내용들이 보일 것이고, 그것은 우리가 만든 Outlet 과 Action 에 대한 코드일 것이다.

Interface Builder 에서 Outlet 과 Action 에 대해서 작업한 내용이 결과적으로 Controller 소스 코드에 저장되는 것이라면, 그 반대의 작업도 가능하지 않을까?
다시말해서, 처음부터 Workspace 에서 MyHelloViewController.m/h 소스코드에 직접 코딩해서 작업하면 되지 않을까 하는 것이다.

물론 가능하다. 조금 익숙해진다면 각자 기호에 따라서 처음부터 코드로 작성하는 것이 편한 사람들도 있을 것이다. 그러나 처음에는 Interface Builer 에서 작업하는 것이 보다 직관적인 것은 사실이다.

한가지 주의할 것이 있는데, 처음부터 소스 코드에서 Outlet 과 Action 을 만들어서 연결하는 작업을 했다면, 반대로 나중에 Interface Builder 를 다시 실행해서 해당 View 의 XIB 내요을 수정하려 한다면, 작성된 컨트롤러 클래스 내용을 IB 로 반영해야 작업에 실수가 없게 된다.

메뉴에서 
Read Class Files... 를 선택하면 아까 Write Class Files... 를 했던 것과는 반대로 클래스 소스 코드에 있는 내용이 Interface Builder 에 반영된다. Workspace 와 IB 사이를 왔다갔다 작업할 때는 꼭 이 점을 잊지말아야 사고를 막을 수 있을 것이다.


별것도 아닌 내용을 너무 장황하게 설명한 것은 아닌가 걱정된다. 그러나 Interface Builder 는 GUI 개발 도구 중에서 가장 쉬운, 그리고 MVC 모델이 완벽하게 실체화 된 개발 도구가 아닐까 감히 생각해본다. 따라서 처음 맥 환경에서 프로그래밍을 시도하려는 사람이라도 조금만 살펴보면 적응할 수 있으리라 생각된다.

또 한가지 명심할 것은, 지금까지 살펴본 것 처럼 View 를 구성하고 Controller 클래스를 만들고, Outlet 과 Action 을 작성하여 연결하는 등의 작업은 Mac Desktop 용 application 을 작성할 때에도 방법이 완전히 동일하다는 것이다. 차이가 있다면 오직 사용하는 UI 아이템들 뿐이다. 따라서, iPhone 프로그래밍 만을 하기 위해 Interface Builder 사용법을 익혔다 해도, 이미 절반 이상은 Mac OS 프로그래머가 된 셈이다.

반대로 생각하면, 기존에 Mac OS 에서 데스크탑용 프로그램을 Xcode 를 사용해서 작성할 줄 알던 사람이라면, iPhone 응용 프로그램은 아주 쉽게 작성이 가능한 것이다.
이 점이 전 세계를 놓고 봤을 때 무료로 배포된 iPhone SDK 를 통해서 곧 수 많은 응용 프로그램이 등장하리라는 예상이 가능한 요인 중 하나다.

맥 프로그래머가 극히 적은 국내에서는, 이 문서와 같은 기초 입문 문서가 많은 이들에게 도움을 줄 수 있으리라 감히 기대해본다.


이제 Controller 클래스가 제구실을 할 수 있도록 만들어보자.

iphone programming : Design patterns

2.5. Design Patterns

객체 지향 프로그래밍(Object-Oriented Programming)을 하는 사람들이 항상 고려하는 것 중 하나가 바로 디자인 패턴(Design Pattern) 이라는 것이다. 이 글을 읽는 분들 중에서도 이것에 대해 이미 잘 알고 있는 사람도 많을 것으로 생각된다. 디자인 패턴은 개념적인 것으로서, 프로그램의 구조를 보다 큰 관점에서 보다 유지/보수 관리를 하기 쉽게 하고, 효율성을 높이기 위한 것이다. 디자인 패턴에 대해서는 풍부한 각종 자료를 쉽게 찾아볼 수 있을 것이다. 
Cocoa Fundamentals Guide 문서에서 디자인 패턴에 대한 부분을 참고해도 좋다.

iPhone SDK 위에서 응용 프로그램을 작성하기 위해서는 다음 세 개의 개념이 중심이 된다.
Delegation



우리 말로 '위임' 이라고 말하는데, 대다수의 프로그래밍 용어들이 그렇듯이 이것도 번역한 용어는 어딘가 어색한 느낌을 지울 수 없다. 각설하고, Delegation 은 iPhone SDK 프로그래밍에서 아주 많이 등장하는 패턴이다.
하 나의 객체가 지정된 다른 객체로 주기적으로 메시지를 보내서, 해당 메시지를 처리할 수 있다면 처리할 것을 요구하는 형태를 말한다. 또는, 특정 이벤트가 발생한 경우 그 이벤트를 지정된 다른 객체로 전달하여 처리할 것을 요구하는 것을 말한다.
사실, 프로그램을 작성하는 입장에서 이것은 단순하다. 전달받는 - 혹은 전달하는 - 이벤트일 뿐이다.
우 리가 위임 이벤트를 만나는 것은 Application 이 실행되는 첫 순간부터다. Application 객체는 초기 시작 처리가 다 끝나고나서 applicationDidFinishLaunching: 이라는 이름의 이벤트를 지정된 객체로 전달한다. 첫 시작부터 Delegation 을 만날 수 밖에 없는 것이 iPhone SDK 프로그래밍이다.

Model View Controller



디자인 패턴에 대해 잘 알지 못하는 사람이라도 MVC 에 대해서는 알고 있을 것이다. iPhone SDK 프로그래밍은 MVC 디자인 패턴에 기초한다.
간 단히 짚어보자면, Model 객체는 프로그램이 사용하는 데이터를 의미하며, View 객체는 데이터를 화면에 표시하는 방법이나 사용자가 데이터를 수정하는 방법을 가지고 있는 객체를 의미한다. Interface Builder 는 이 View 를 손쉽게 작성할 수 있도록 도와준다. Controller 객체는 Model 과 View 사이에서 각종 처리를 담당하고 둘 사이를 연결하는 것이다. 쉽게 생각해서 우리가 프로그래밍 언어로 작성하는 프로그램 코드의 대부분은 Controller 가 된다.

Target - Action



만일 화면에 있는 버튼을 손가락으로 누른다면, 이벤트가 다른 오브젝트로 전달된다. 그 이벤트를 받은 오브젝트는 이벤트를 해석하고 그에 알맞는 명령을 수행하게 된다. 이 단순한 메카니즘을 Target-Action 패턴이라고 한다. 단순하지만 앞서 예로 들은 버튼의 경우처럼, 대부분의 iPhone 프로그래밍에서 항상 등장한다.

위의 세 가지 용어는 iPhone SDK 프로그래밍에서는 상식과도 같은 개념이 된다. 모든 것이 세 가지 디자인 패턴 속에서 이루어진다.


2.6. 프로젝트 생성과 기본 코드.

다시 Xcode 를 실행해서, 새로운 프로그램을 작성해 보자. 완전히 새로운 프로젝트를 생성해서 시작해도 좋지만, 앞에서 실행해 본 Hello, iPhone 프로그램을 수정해도 상관 없다. 새로운 프로젝트를 만든다면 마찬가지로 View Based 템플릿을 사용해서 시작하도록 한다.

만일 기본적인 View 조차 없는 프로젝트라면, View 를 생성해서 프로젝트에 포함시키는 작업을 우리가 직접 해주어야 한다. 그러나 하나의 View 가 처음부터 포함되어 있는 템플릿 덕분에 많은 시간을 절약할 수 있다.

필자는 
MyHello 라는 이름의 새로운 프로젝트를 만들었다. 앞으로 편의상 이 이름을 기준으로 각 파일들의 이름을 부르도록 하겠다.

현재, 프로젝트에는 두 개의 XIB 파일이 있다. 여러분이 나중에 각종 프로그램을 작성하다보면 하나의 프로젝트에 여러 개의 XIB 파일이 포함될 것이다.
그렇다면, 프로그램이 처음 실행될 때 어떤 XIB 파일이 처음 사용되는 것일까?

고정된 이름을 가진 XIB 파일이 처음에 사용된다는 식의 원시적인 규칙은 아니다. Workspace 에서 다음 그림과 같이 Resources 항목에 등록된 파일들을 살펴보면, 그곳에 
info.plist 라는 파일이 있다. 이 파일을 선택하면, workspace 에서 그 내용을 보여준다.



info.plist 의 내용에는 작성하는 응용 프로그램의 기본 설정 사항이 저장되어 있으며, 그림에서 보면 아래쪽 항목에 처음 참조하는 XIB 파일이 지정되어 있는 'Main nib file base name'항목도 있다는 것을 볼 수 있다.
즉, iPhone 응용 프로그램이 실행될 때 info.plist 에 있는 각종 초기 설정에 따라 실행 준비가 이루어지며, 처음 사용할 XIB 파일을 선택하는 것도 여기에 있는 설정 값에 따라서 동작하는 것이다.
(여기서도 아직 nib 라는 용어가 xib 로 변경되지 않았다. 점차 모든 용어를 xib로 변경하는 중이니까, 이것도 
나중에 나올 버전의 Xcode 에서는 변경될 것으로 생각된다)

프로젝트가 저장되어 있는 폴더를 Fiinder 에서 직접 열어보면 info.plist 파일이 저장되어 있는 것을 쉽게 찾을 수 있다. 직접 더블 클릭하면 Property List Editor 가 실행되어 Xocde 의 Workspace 에서 보여준 것과 같은 내용을 볼 수 있다. 물로 양쪽 모두 수정도 가능하다. 강제로 텍스트 편집기 같은 에디터에서 이 파일을 열어보면, 단순한 xml 문서 파일임을 알 수 있다.

자, 별로 어렵지 않을 것이다. info.plist 의 자세한 분석은 그리 중요한 것이 아니다. 이제, 프로그램이 실행되면서 property list 에 지정된 XIB 파일이 읽혀진다는 것을 알았다.
그러면, 그 다음 어떤 일이 일어나는가?

MainWindow.xib 항목을 더블 클릭하여, Interface Builder 를 실행해 보자.

IB의 창을 보면, 이전에 보았던 View 의 XIB 파일과는 어딘가 다르게 보인다. IB 의 창에는 아이콘도 두 개 정도 더 있는 것 같고, View 창의 모습도 다르다.




View 창이 재미있다. 실제 iPhone 의 배터리 상태 및 통신 상태 표시칸도 보인다. 그리고 우측 상단에는 작은 휘어진 화살표가 있는데, 이것을 클릭하면 View 창이 실제로 90도 회전한다. 처음 직접 클릭해보면 기대 이상의 동작에 깜짝 놀랄 것이다.

지금 살펴볼 것은 MainWindow.xib 창에 있는 객체 아이콘들이다. 여기에는 처음 보는 아이콘들이 있는데, 그 중에서 MyHello App Delegate 라는 객체가 보인다. 이것을 선택한 후 속성 창에서 connections 탭을 선택해서 그 항목들을 살펴보자.



Referencing Outlets 로 하나의 Outlet 이 연결되어 있는데, delegate 가 File's Owner 와 연결되어 있다.(Outlet 이 뭔지는 나중에 다루자) File's Owner 객체를 선택해서 connections 를 살펴보면, 반대로 delegate 가 MyHello App Delegate 객체와 연결되어 있다는 것을 확인할 수 있다.

앞에서 말한대로, File's Owner 는 Application 자체의 인스턴스 객체를 의미한다. 여기에 delegate 클래스로 MyHello App Delegate 가 등록되어 있는 것이다. 고맙게도, MyHello App Delegate 클래스를 생성하고 그것을 File's Owner 의 delegate 메시지를 받도록 등록되어 있는 이유는 모두 템플릿이 기본적으로 자동 생성해 준 덕분이다.

이렇기 때문에, MyHelloAppDelegate.m 객체로 응용 프로그램의 delegate 이벤트가 전달된다.

이렇게 지정된 규칙에 따라, MyHello 프로그램은 처음 실행되면서 최초의 MainWindow.xib 에 연결된 delegate 연결을 보고서 '위임'메시지를 보내기 시작한다.

그렇게 처음 보내기 시작하는 delegate 메시지는 바로 
"나는 실행준비 다 끝났어. 너할거 있으면 해" 를 의미한다.
그 메시지의 이름은 
applicationDidFinishLaunching: 이다. Xocde 로 돌아와서, MyHelloAppDelegate.m 의 소스 코드를 살펴보자.
다음과 같은 코드가 생성되어 있는 것을 확인할 수 있을 것이다.



- (void)applicationDidFinishLaunching:(UIApplication *)application {    
    
    // Override point for customization after app launch    
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
}

이것은 Objective-C 프로그래밍 언어의 문법으로 되어 있는 소스 코드다. C++ 와 뭔가 유사성이 있어 보이기도 하는데, C 언어와는 좀 달라보인다.

이 문서에서는 Objetive-C 언어에 대한 상세한 설명은 하지 않는다. 개략적인 내용은 뒤에서 다시 정리하도록 하겠다. Objective-C 언어에 대한 설명은 애플 개발자 사이트에서 충분히 많은 문서를 찾을 수 있을 것이다.

간단히 설명하자면 applicationDidFinishLaunching: 메시지를 받아서 처리하는 코드를 작성한다는 것은, C 언어로 생각할때 applicationDidFinishLaunching: 이라는 이름의 함수를 만드는 것과 같은 말이다. 단, 메시지 전달은 함수 호출과는 달리 동적인 개념이며, 메시지를 받는 객체에서 해당 메시지를 처리할 수 있는 코드가 없다고 해서 컴파일 시 링크에러가 난다거나, 런타임에 에러가 발생하지는 않는다는 점만 명심하자.

위 코드의 내용을 보면, 윈도우에 하나의 view 를 추가하고나서, 그 윈도우를 화면에 표시하도록 해 주는 내용임을 알 수 있다.
이 런 식으로, MyHelloAppDelegate.m 에는 MyApp 프로그램의 Delegation 메시지를 처리하는 코드들이 있으며, 현재는 없지만 필요한 delegate 메시지 처리 코드를 추가할 수도 있다. 이와 함께 헤더 파일도 살펴보면서 코드의 스타일을 짐작해 보자.

프로그램이 종료될 때는 dealloc 메시지를 전달한다. 여기서는 메모리를 해제하는 코드들이 있게 된다. 이처럼 delegate 객체에서는 응용 프로그램이 위임하는 각종 이벤트를 받아서 처리하게 된다.



이제 기본적으로 초기화 과정에 대한 부분들을 살펴보았다. 이제 다른 부분을 한번 살펴보자. 계속 보다시피, 우리가 만든 프로젝트는 기본 템플릿에 의해 하나의 View 를 가지고 있으며, 그것은 이미 Window 화면에 연결되어 있는 상태다.

MVC 디자인 패턴을 떠올려보자. 여기 하나의 View 가 존재하므로, 있어야 할 것은 나머지 Model 과 Controller 이다.

앞서 말할 것 처럼 Model 은 프로그램이 처리할 자료를 말한다. 현재 우리가 작성할 프로그램은 별로 하는일이 없기 때문에 Model 에 대한 부분은 잊어버리자. 그러면 남는 것은 Controller 인데, 이것도 템플릿에 의해 MyHelloViewController.m 이라는 이름으로 해당 View 와 연결된 Controller 코드가 자동 생성되어 프로젝트에 포함되어 있는 것이다. 

MyHelloViewController.xib 를 더블 클릭하여 이것도 Interface Builder 에서 열어보자. Interface Builder 는 이미 열려있는 MainWindow.xib 파일과 동시에 보여줄 수 있다.




앞에서 해봤던 대로 xib 의 내용을 조금 살펴보자. 일단 주목할 것은, 여기에 있는 
File's Owner 는 응용 프로그램 자체가 아니라 Controller 의 인스턴스를 의미하는 객체다.
즉, MyHelloViewController.m 객체의 인스턴스를 의미하는 아이콘이다. 그리고 File's Owner 객체와 View 객체는 서로 View 컨트롤러의 
view Outlet(아웃렛) 에 의해 연결되어 있다. 마찬가지로 connections 창에서 서로의 연결을 확인할 수 있다.


outlet 은 단지 xib 파일에서 아이템을 서로 연결하는데에 사용되는 인스턴스 변수와 같은 것이다. MyHelloViewController 에 이런 인스턴스 변수가 있는 이유는, 모든 View 는 UIViewController 에서 상속되기 때문이다.


템플릿에 의해 제공된 MainWindow 와 View 는 이상 살펴본 형태로 서로 연결되어 구성되어 있다. 조금 더 살펴본다면 어느정도 감은 잡을 수 있을 것으로 생각된다. Objective-C 언어와 각종 용어의 낮설음은 일단 참고 그냥 넘어가보자.
지나보면 별거 아니다!