Xcode4 CurrencyConverter: Difference between revisions
Onionmixer (talk | contribs) (오타내용 수정) |
(No difference)
|
Latest revision as of 15:31, 8 January 2014
- Currency Converter for Xcode 4 Version
개요
이 강좌는 Xcode 이전의 project builder 시절에 만들어진 apple 의 문서를 기준하여 최신의 내용을 기존의 내용을 다시 한번 만들어나가는데 그 목적이 있습니다. 모자란 설명은 기존의 문서를 참고해 주시기 비랍니다.
이 강좌가 다른 강좌에 비해 결과물이 간단함에도 불구하고 한번쯤 살펴보아야 하는 이유는 다음과같다
- xib 를 이용한 windows UI를 다룬다.
- windows UI 의 files owner 를 통한 instance object 의 연결과 instance object 와 실제 코드상의 class 연결을 통한 UI to Objective-C code 의 delegate 를 볼 수 있다.
- MVC의 간단한 에제를 볼 수 있다.
MVC 가 대체 뭔가요?
일반적으로 설명되는 MVC 의 구조는 다음과 같습니다.
Controller 외에는 서로 연결되는 부분이 전혀 없죠. 이론만으로 보자면야 객체지향의 완벽에 가까운 보기라 할 수 있을 겁니다.
여기 원문에서 제시되는 설명을 인용해보곘습니다.(문맥이 어색한 부분은 약간씩 수정한 부분이 있습니다)
▶ | Model-View-Controller 는 Smalltalk-80 에서 유래하였습니다. MVC 는 같은 응용프로그램 내에 있는 객체들을 Model, View, Controller 라는 추상적인 경계로 나누어 서로 소통하는 구조로 되어있습니다.(from Apple) |
Model Object(from Apple)
이 객체는 전문적인 지식 또는 기술을 의미합니다. Model 객체는 데이터를 포함하고 있으며, 그 데이터를 조작하는 로직을 정의하고 있습니다. 예를들자면 '고객' 이라는 객체는 비즈니스용 프로그램에서 자주 사용되는 Model 객체입니다. Model 객체는 고객에 관련 대표적인 정보를 나타내는 데이터를 가지고 있으며, 그 정보로부터 새로운 데이터를 계산하고 엑세스 해주는 알고리즘에 접근합니다. 더욱 전문화된 Model Class 의 예로는 기상관측시스템의 'Front' 라는 Class 를 들 수 있는데, 이 Class 의 객체는 날씨 전말을 나타내는 데이터와 정보를 가지고 있습니다.
Model 객체는 직접적으로 보여지지 않습니다. 또한 이들은 다양한 플랫폼(환경이라는 의미인거같습니다)에서 이동,지속,분배,재사용 될 수 있습니다.
View Object(from Apple)
View 객체의 Paradigm 은 사용자 인터페이스에서 볼 수 있는것들(Windows, Button, etc)을 말합니다. View 객체는 표시되는 데이터에 대해서는 알지 못합니다. Application Program Kit 는 Window, TextField, ScrollView, Browser 등 필요한 모든 View 객체를 제공합니다. 또한 새로운 방법(Graph 등)으로 자신만의 View 객체를 만들어 데이터를 표시할 수 있으며 프로그램에 적합한 새로운 방법으로 Window 내에서 View 객체들을 그룹화 할 수도 있습니다. 특히 Kit(Application Kit) 내의 View 객체는 재사용성이 매우 높기 때문에 프로그램간에 일관성을 유지할 수 있습니다.
Controller Object(from Apple)
Controller 객체는 Application Program 내에서 Model 객체와 View 객체 사이의 매개체로 작용합니다. 일반적으로 하나의 프로그램 또는 하나의 Window 에는 1개의 Controller 객체가 있습니다. Controller 객체는 Model 객체와 View 객체 사이에서 데이터를 전달하는 역할을 합니다. 또한 nib(Xcode 4 에서는 xib 입니다) 파일 로드, Window와 프로그램의 대리자(Delegate) 역할등 프로그램 특유의 잡다한 일들을 진행합니다. 프로그램에 대해 Controller 객체가 하는일은 매우 구체적이기 때문에 프로그램 코드의 많은 부분을 차지하면서도 일반적으로 재사용은 불가능합니다.(Controller 객체가 모두 재사용될 수 없다는것은 아닙니다. 설계를 잘 한다면 재사용이 가능하겠죠)
Controller 객체의 핵심적인 역할인 Model 과 View 사이의 중개자 역할때문에 Model 객체는 Interface(UI)의 상태와 Event 등에 대해 알 필요가 없으며, View 객체는 Model 객체에 대한 Program Interface를 알아야할 필요가 없습니다. 직접 작성한 View 각체와 Model 객체는 Interface Builder 에 있는 Palete 에서 다른사용이 사용할 수 있게 할 수 있습니다.
이 강좌에서 사용되는 MVC 에 대하여
이 강좌에서 제작되는 프로그램은 이런 구조를 조금 더 Extream 하게 가져가는걸 목적으로 함으로서 원래의 구조와는 약간의 변경이 생기게 되니 관련되는 부분은 참고 부탁드립니다.
Application 의 기본전제
원래문서의 Application 에서 설명하는 것들을 몇가지 중요한 필요조건을 나열해 보도록 하겠습니다.
- MVC(Movel-View-Controller)의 구조로 작업한다
- instance object를 사용한다.
원래 문서에 있는 내용대로 Class Diagram 을 간략하게 표현해보면 다음과 같습니다.
이 어플리케이션은 아래와같은 전제와 객체구조를 가지게 됩니다.
- Class 명은 Conv 로 정의한다
- Converter :: 통화량을 게산해서 값을 반환한다. Model 에 해당됨
- ConverterController :: Converter 객체와 AppDelegate 사이의 활동을 조정하는 클래스. Controller 에 해당됨
- ConvAppDelegate :: xib 파일에서 정의된 UI 객체들에 대한 동작을 정의하는 클래스. View 에 해당됨.
- xib 파일 :: AppDelegate 에 IBOut, 및 Action 으로 연결되는 사용자 UI
이러한 내용을 기초로 하면 다음과같은 관계를 생각해볼 수 있습니다.
물론 굳이 이러한 구조를 가져가야할 필요도 없고 더 단순화 시킬 수 있는 부분도 많겠습니다만, 여기서는 MVC에 대한 예제를 같이 보여주는것을 목표로 하고 있기 때문에 필요한것들은 다 작업하며 진행하도록 하겠습니다.
강좌의 내용은 다음과같은 순서로 진행됩니다
- Project의 생성
- 사용자 UI 제작
- Delegate 파일에 UI 의 element 를 연결
- Converter 클래스 구현
- ConverterController 클래스 구현
- 각 클래스간의 연결
- 개발한 프로그램에 대한 디버그 및 실행
Xcode를 이용한 Project의 생성
윗 그림에서 보이듯이 XCode 4 를 처음실행하면 몇가지를 선택할 수 있는 화면이 나옵니다. 우리는 여기서 새로 프로젝트를 생성할 것 이기 때문에 "Create New Xcode Project" 를 선택해줍니다.
새로운 프로젝트를 위한 template 을 선택할 수 있으며 여기서 우리가 개발할려고 하는것은 Foundataion Framework 을 위한 프로그램이기때문에 "Cocoa Application" 을 선택해줍니다.
Project 에 대한 여러가지 정보들을 기입합니다. 신경써야할 정보는 다음과 같습니다.
- Product Name :: 만들어질 프로그램의 이름인데 당연하겠죠?
- Organization Name :: 저작자 정보입니다.
- Compane Identifier :: 기본적으로 domain rule을 따른다. (ex: com.naver 등의 규칙)
- Class Prefix :: 기본적으로 생성되는 Class의 prefix를 정한다. 여기서는 "Conv" 라는 이름을 사용한다
- [CheckBox] Create Document-Based Application :: 여기서는 check를 하지 않는것으로 한다. 왜냐하면 Document 기반의 개발방법을 사용하지 않을것이기 때문이다. 때문에 unchecked 하도록 한다
위의 내용이 작성되면 "Next" 를 눌러서 다음단계로 진행하도록 합니다.
이제 설정대로 만들어지게될 프로젝트를 어디에 저장할것인가를 지정하게 됩니다. 디렉토리를 지정한다음 "Create" 버튼을 눌러서 프로젝트 생성을 완료하도록 합니다.
생성된 Project 의 구성요소
프로젝트 자체의 구성요소에 대해 알아보기전에 xcode 의 Project 화면을 먼저 살펴본다음 프로젝트의 구성요소들에 대해 알아보기로 하겠습니다. 아래의 화면을 보겠습니다. 이 화면은 Xcode의 시작화면에서 "Learn about using Xcode" 를 누르면 나오는 화면입니다.
Xcode 의 기본 구성요소
위의 그림에서 설명된 부분을 하나하나 짚어가면서 설명하도록 하겠습니다. 일단 크게 4 가지의 영역으로 나눌 수 있습니다.
프로젝트에 관련된 File 및 resource 에 대한 탐색을 할 수 있습니다.
Editor area
프로그램의 코드를 편집할 수 있는 영역입니다. 사용자 UI(xib등)도 편집할 수 있습니다. iOS 개발의 경우는 Phone Application UI 가 되겠군요.
Debug area
디버깅을 진행하는경우 관련된 정보들을 참고할 수 있는 영역입니다. 평상시에는 사용하지 않을 수 있습니다. 일반적으로 Xcode로 작업할때 View >> Assistant Editor 를 열어놓고 주로 사용하는 영역이 되기도 합니다.
Utility area
객체 또는 코드에 대한 Inspect 정보들을 표시한다거나 라이브러리등을 표시하게 됩니다.
세부부분 설명
각 세부부분에 대한 설명은 다음과 같습니다.
Toolbar
Xcode의 기본적인 기능(run 이라던가)과 정보등이 표시됩니다. Xcode 의 실행창에 영향을 끼칠 수 있는 기능버튼과 정보표시창등이 있습니다.
Project 에서 다루는 File 및 resource 에 대한 도구들이 있습니다. Class 의 계층을 볼 수 있기도 하고 Class 내에서 원하는것을 검색할 수 있는 도구를 제공하기도 합니다. 그외 디버깅에 관련된 항목들을 나열할 수 있는 기능도 가지고 있습니다.
Breakpoint gutter
중단지점을 표시할 수 있는 영역입니다. 중단지점을 create/enable/disable 할 수 있으며 생성한 중단지점을 없애려는 경우는 Drag 해서 코드편집창쪽으로 Drop 하면 됩니다.
Focus ribbon
일반적으로 computer programming language 로 프로그래밍을 하는경우는 개념상의 block 으로 지정되는 "영역(focus)" 라는게 존재하게 됩니다. depth가 깊어질수록 짙은 색상으로 표시되며 같은 색상끼리는 같은 대상 영역 이라고 판단하면 됩니다. 그런 영역을 색상으로 표시해주는 영역입니다.
Filter bar
Navigator area 에 표시되는 내용들을 필터링하는 조건을 설정할 수 있는 부분입니다. Navigator selector bar 에서 선택한 내용에 따라 필터링을 지정할 수 있는 조건 자체도 바뀌게 됩니다.
Debug bar
디버깅을 할때 step 등을 사용할 수 있는 기능들이 모여있는 곳입니다.
Library pane
Xcode 에서 사용할 수 있는 라이브러리들이 모여있는 곳입니다. Xcode 4부터 내장되어버린 Interface Builder 에 대응하는것으로서 UI를 설계할때 사용할 수 있는 element 들을 모아둔 곳이라고 보면 되겠습니다. 여기서 원하는것을 Drag & Drop 하는 방식으로 작업하게 됩니다.
Library selector bar
Library pane 에 대해 사용할 수 있는 Library 의 종류를 변경할 수 있도록 합니다. 다음과 같은 종류가 있습니다.
- File Template Library :: iOS 용과 Mac 용을 고를 수 있습니다. 여기에 보이는 내용은 Navigator area 로 Drag & Drop 이 가능합니다. (아마 잘 쓸일은 없을거같습니다만....)
- Code Snippet Library :: iOS, Mac, User(사용자정의) 등을 고를 수 있습니다. Editor area 로 Drag & Drop 이 가능하며 Drop 한곳에 Drag 한것에 해당되는 기본 코드 템플릿이 삽입됩니다.
- Object Library :: Interface Builder 의 화면에 사용할 수 있는 element 들의 모음입니다.
- Meda Library :: 코드를 편집하고 있는 경우에는 Class 이름등이 삽입되고 Interface Builder 화면에서는 해당되는 객체를 추가할 수 있습니다.
Inspector pane
현재 어떤작업을 하고있는가에 따라 내용이 많이 달라지는 영역입니다. 예를들어 코드를 편집하고 있는 경우에는 코드가 소속된 파일의 정보가 나오게 됩니다. Interface Builder 화면의 경우에는 선택한 객체(element)에 대한 정보가 나오게 됩니다.
Inspector selector bar
Inspector pane 에서 어떤 정보를 뿌려주고 있는가에 따라 사용할 수 있는 기능이 바뀌게 됩니다. instance object 의 경우는 해당 객체가 참고하는 Class 도 설정할 수 있습니다.
Jump bars
Editor area 에는 공통적으로 따라다니는 기능으로서 Navigator area 에서 파일을 선택하는것만이 아니라 좀 더 편하게 여러개 파일 및 디렉토리를 옮겨다닐 수 있게 해줍니다.
프로젝트의 기본 구성요소
이제부터 생성한 프로젝트의 기본 구성요소에 대해 알아보겠습니다.
위의 그림파일에 보이는것처럼 가장 왼쪽의 영역에는 현재 프로젝트에 관련된 File 과 resource 파일들이 기본적으로 나열되어 있습니다. 이중 프로젝트에 신경을 써야할만한 파일들 몇개만 소개하도록 하겠습니다.
- _ClassName_AppDelegage.h :: 시작할때 Class 이름을 Conv로 주었다면 ConvAppDelegate.h 이라는 이름으로 파일생성이 될것입니다. ConvAppDelegate 에 대한 @interface 가 선언되어 있습니다. 이 과정에서 ConvAppDelegate 클래스 선언이 없는것은 이후에 Interface Builder 화면에서 MainMenu.xib 파일을 편집할때 다시 한번 알아보도록 하겠습니다. 여기서는 interface 를 선언하면서 NSObject 라는 Class 의 상속을 받아 구현하는걸로 코드가 진행되어 있습니다.
- _ClassName_AppDelegage.m :: 시작할때 Class 이름을 Conv로 주었다면 ConvAppDelegate.m 이라는 이름으로 파일생성이 될것입니다. ConvAppDelegate 에 대한 @implementation 이 선언되어 있습니다.
- MainMenu.xib :: Interface Builder 에서 사용하는 파일입니다. 사용자 UI에 대한 내용이 담겨있으며 해당되는 파일을 편집하려고 Xcode 내에서 클릭하는경우에는, 코드편집창 대신 Xcode에 Embed된 Interface Builder 의 화면이 보이게 됩니다.
사용자 Interface의 편집
MainMenu.xib 파일을 클릭해서 화면을 위와같이 바꿔주시기 바랍니다. 물론! 아래쪽의 에디터 부분도 가능하면 위에 보이는 화면처럼 바꿔주실것을 권장합니다(VIew >> Assistant Editor 메뉴부분 참고). 화면상에 보이는 메인창의 크기를 보이는것처럼 줄여주시고 편집하기 편한상태로 봐주시면 되겠습니다. 이제부터 몇가지를 추가적으로 상세히 살펴본뒤 UI 의 구성작업을 진행하도록 하겠습니다.
Interface Builder 에 대한 추가설명
위의 화면에서 볼 수 있듯이 오른쪽 아래의 영역에서 Object Library 를 선택하면 각 객체를 click 했을때 조금만 기다리면 객체에 대한 도움말을 볼 수 있습니다. 이제부터 진행되는 내용에서는 이 도움말에서 나오는 Class 이름으로 설명을 하도록 하겠습니다.
위의 부분은 예전의 Project Builder 시절에 사용되었던 팔레트와 비슷한 용도로 쓰이는 영역입니다. 이후에 설명하게 되겠습니다만... Windows의 Delegate 설정과 그 Delegate를 받는 코드와의 연계작업등 여러가지 용도로 사용되므로 주의해야할필 요가 있습니다.
기본 Windows에 객체를 배열하기
일단 화면에 보이는 Windows에 객체를 배열합니다. 아래와같은 순서로 객체를 배열하도록 합니다.
- 오른쪽 아래 부분에서 NSTextField::TextField 를 선택한다음 Drag & Drop 으로 Windows에 하나 배열한다.
- 배열한 객체를 선택한 다음 ⌘+D(Cmd+D) 를 입력한다. 선택된 객체가 복사된다.
- 같은 방법으로 객체를 하나 더 복사한다. 이렇게 TextField 를 3개를 놔둔다음 보기좋게 정렬한다.
- 제일 아래쪽에 놓이게될 TextField 한개만 선택한다음 Inpector 에서 Atttibute 를 편집하도록 한다. Behavior 의 값을 Selectable 로 변경한다.
- 오른쪽 아래 부분에서 NSTextField::Label을 Drag & Drop 으로 Windows에 하나 배열한다.
- 같은 방법으로 Label 을 3개로 만들어서 TextField 의 좌측에 차례대로 배열한다. 이후 Label 의 Attribute 에서 Alignment 를 우측정렬로 바꾼뒤 Title 의 값을 각각 아래와같이 바꿔준다.
- Label_01::Title = "Exchange Rate per $1:"
- Label_02::Title = "Dollers to Convert:"
- Label_03::Title = "Amount in Other Currency:"
- 오른쪽 아래 부분에서 NSBox::HorizontalLine 을 Drag & Drop 해서 이쁘게 배치한다.
- 오른쪽 아래 부분에서 NSButton:PushButton 을 Drag & Drop 해서 이쁘게 배치한다.
- 배치한 PushButton 의 Title 을 Convert 로 변경하고 버튼의 크기를 알맞게 조절한다
- 배치한 PushButton 의 Attribute 에서 Key Equivalent 를 클릭한디음 키보드의 "Enter" 키를 눌러준다. 이후로 이 버튼은 Enter Key 에 반응하게 된다.
위의 과정으로 인한 결과물의 보이는 모습이 다음과같은 모양이 되었다면 기본 배치작업과정은 종료입니다.
TextField 간에 Tab Order 구성하기
Interface Builder 에서는 아래와같은 과정을 통해서 현재객체와 다음객체간의 관계를 설정할 수 있습니다.
- 화면상에 배열한 TextFiled 중 첫번째 TextFiled 를 선택합니다.
- Ctrl 키를 누른채로 첫번째 TextFiled 에서 바로 아래의 TextFiled 로 mouse 커서를 드래그합니다. 그럼 그림과같은 화면을 볼 수 있습니다.
- mouse 클릭버튼을 떼면 아래 그림에 보이는것처럼 popup 메뉴을 볼 수 있습니다. 이중 Outlets >> nextKeyView 라는 항목을 선택해주세요.
- 이후 다시 첫번째 TextFiled 를 click 해서 선택한다음 mouse 의 오른쪽 버튼으로 popup menu를 불러내면 아래처럼 객체간의 outlet 이 연결된것을 확인할 수 있습니다.
위의 과정을 기초로 해서 두번째 TextFiled 의 nextKeyView 를 첫번째 TextFiled 로 연결해주세요.
Windows 에 대한 initialFirstResponder 설정하기
위의 그림에 보이는 부분을 주의해 주시기 바랍니다. 그리고 Window - CurrencyConverter 라고 나와있는 부분에서 mouse 의 오른쪽 버튼을 클릭해서 popup menu를 불러주시기 바랍니다.
등장한 popup menu 에서 Outlets >> initialFirstResponder 항목을 봐주시기 바랍니다. 오른쪽에 보면 동그라미가 있죠? mouse 커서를 가져가면 + 기호로 변하게 됩니다. 이때 mouse click & drag 로 화면에 보이는것처럼 선을 가장 첫번째의 TextFiled 로 가져가서 drop 해주세요. 그러면 해당되는 outlet 이 연결됩니다.
이후 화면을 보면 popup 에서 outlet 이 새로 연결된것을 확인할 수 있습니다.
지금 이 작업은 처음 application 이 구동되었을때 입력의 focus 를 어디로 놓을까에 대한 부분입니다. 고로 이 작업 이후에 application 을 구동하게 된다면 자연히 첫번때의 TextFiled 에 뭔가를 입력할 수 있는 상태로 자동으로 준비가 됩니다.
Windows 의 Attribute 조정
이렇게 만들어진 Window의 크기를 조정하게 하면 나중에 resize 시 Layout 이 깨지는 현상을 경험하게 됩니다. 일단은 resize 가 안되게 기능을 제한하도록 하겠습니다.
위에 보이는것처럼 windows 를 click 하고 오른쪽의 Inspector 부분의 Attribute 부분을 확인합니다. 이후 아래화면처럼 Attribute 에서 resize 를 uncheck 합니다.
작업된 Interface 의 테스트
Xcode의 화면 왼쪽 상단을 보면 Run 이라는 버튼이 있습니다.
버튼을 눌러서 만들어진 interface 가 정상이라면 아래와같은 구동화면을 확인할 수 있습니다. 화면을 확인했으면 ⌘+q(Cmd+q) 를 눌러서 application 을 종료합니다.
Interface Builder 에서 생성한 UI 와 instance Object. 그리고 delecate 의 관계
이 부분이 기존 문서에는 없던 부분이라 좀 생소할것 같아서 세부적인 설명이 필요한 부분이라 생각되어 별도로 내용을 추가하도록 합니다. (명확한 설명이 없이는 좀 헷갈리는 부분이기도 합니다)
▶ | 지금 이 과정에 대한 작업부분은 과정이 끝나는 이후로 사용하지 않습니다. 고로 현재시점까지의 소스코드에 대한 백업을 권장합니다 |
기존의 문서에서는 Interface Builder 의 Palate 에서 객체를 생성하고 이를 Program Code 로 연결하는 작업등을 진행했었지만 Xcode 4에는 그런작업을 할 필요는 없습니다. 사실 Xcode 4에서 Project 를 Cocoa Applicataion 으로 생성한 시점부터 지금부터 설명하려는 작업이 이미 기본적으로 되어있기 때문입니다. 이제부터 Interface Builder 에서 작업된 UI 가 어디로 어떻게 연결되어 있는지에 대한 부분을 조금만 살펴보도록 하겠습니다.
그림에 보이는 부분에서 mouse 의 우클릭을 하도록 합니다. 그러면 popup menu 를 확인할 수 있습니다. popup menu 를 좀더 자세히 살펴보도록 할까요?
popup menu 에는 이미 delegate 가 Conv App Delegate 로 연결되어있는걸 확인할 수 있습니다. 흐음.. 그래요. 연결된건 좋은데 대체 이건 어디로 연결된걸까요?
이야? 관련되었을거같은 이름을 찾다보니 생각외로 가까운데 있었네요? 그럼 이 객체를 클릭해보도록 하겠습니다. 이후 Inspector 쪽의 Identity 부분을 보도록 하겠습니다.
호오.. 이 객체의 Class 는 ConvAppDelegate 로 지정되어 있네요?... 그럼 이녀석은 분명 어딘가에 있을겁니다.. 어디있는지 한번 찾아보기로 할까요?
역시.. ConvAppDelegate.h 파일에 이미 선언되어있는 @interface ConvAppDelegate 로 연결되어 있었군요!.
이 강좌의 처음 부분에서 제가 ConvAppDelegate.h 파일을 언급하면서 Class 선언에 대해서는 아래부분에서 살펴보자는 얘기를 한걸 기억하신 분이 있을까요? 맞습니다. 굳이 Code 에서 Class 를 선언하지 않아도 이미 xib 파일에서 instance class 형태로 존재를 하고 있기때문에 해당되는 instance class 의 구현(implementation)만 Delegate 되어있으면 되는거였습니다.
그렇다면 대체 Delegate 는 뭘까요? 그것은 Objective-C 에서의 Delegate 부분에서 좀 더 자세히 보도록 하고 여기서는 대략만 설명하도록 하겠습니다.
Interface Builder 에서 배열되고 놓여지는 객체들은 전부 Inspector >> Identity 부분에서 해당되는 객체가 가리키는 Class 를 지정할 수 있습니다. 그리고 Xcode 는 이런 정보들을 기초로 program code 에서 특정 객체(Class)를 불렀을때 UI 상의 어떤 객체가 동작하게 될지를 알 수 있는거죠. Xcode 에서는 이런 연결들을 통해 프로그램을 제어합니다. 이렇게 UI 객체의 Class 등을 정의한것을 Delegate(위임)' 라고 하는것 같습니다.
그렇다면..... 내가 별도의 Class 를 만들어서 이것을 Delegate Class 로 지정할 수는 없을까요? 그래요.. 안될리가 없겠죠. 이제부터는.. 크게 쓸모는 없지만 어떤 구조로 작동되는지를 알아보기 위해 번외적인 작업을 진행함으로서 어떤식으로 Delegate 를 연결하는지를 아주 조금 더 알아보도록 하겠습니다.
Form 의 Delegate 변경하기
일단 Delegate 를 변경하기 위해서는 Windows의 Delegate 를 받아줄 뭔가가 필요합니다. 그럼 어디서 부터 시작을 해야하는게 맞는걸까요?
Delegate 의 대상이될 Class 생성
Delegate 에는 타겟이 필요합니다. 누군가 나의 대리자가 되어야 할 필요가 있다면 없는 존재를 대리자로 내세울수는 없겠죠. 일단 Delegate 의 교환에는 교환대상이 될 새로운 Class 가 필요합니다.
위 화면에서 보이는것처럼 Project 위에서 popup 메뉴를 이용해서 새로운 파일을 생성합니다. (사실 나중에 안겁니다만.. CurrencyConverter Folder 아이콘위에서 파일을 생성했다면 아래에 설명하는 과정중 하나가 줄었을겁니다)
New File 메뉴를 눌렀을 경우 나오는 화면입니다. 우리는 새로운 Class 를 추가하려고 하는 것이기 떄문에 Objective-C Class 를 선택해줍니다.
새로 만들게될 Class 의 이름입니다. 어차피 Delegate 의 테스트에 사용할거고 본 강좌에서는 Conv 라는 prefix 를 사용하기로 이미 정했기때문에 Class 의 이름은 ConvDelegator 로 정해줍니다.
이제 Class 파일을 저장할 경로를 설정할 때입니다. 대략 프로젝트 디렉토리 아무곳에나 생성하기로 합니다. (어차피 테스트하고 지울거니깐요. 이전단계까지 백업은 미리 받아놓으셨겠죠?)
오호 원하는 Class 의 내용을 담을 파일이 새로 생성되었습니다. 어라? 그런데 원하는 Folder 바깥쪽에 있군요. 관리의 편의성을 위해 2 개 파일을 선택한후 바로 아래쪽의 Folder 로 Drag 해줍니다.
위와같은 파일의 목록이 보이게 되면 일단 Class 파일의 생성과 배치는 성공적으로 진행이 된겁니다.
생성된 파일중 .h 라고 되어있는 header 파일을 보겠습니다. @interface 부분이 선언되어 있는게 보이는군요. 이제 이 선언부에 protocol 관련 내용을 조금 적어주겠습니다.
위와같이 NSApplicationDelegate' 부분을 추가해줍니다. 이 작업의 의미는 나는 이제 Delegate 를 받을 수 있어요 라는 의미라느군요(아.. 출처가 기억이.....)
자 이제 Class 관련 부분에서 코딩으로 해야할 부분은 끝났습니다. 이제 다음과정으로 진행해볼까요?
Interface Builder 에서 instance Object 설정하기
Interface Builder 화면에서 NSObject::Object를 선택합니다.
화면처럼 선택한 Object 를 Interface Builder 의 팔레트에 얹어줍니다.
얹은 Object 에 대한 기본적인 내용을 잠시 살펴보겠습니다. 일단 instance Object 의 현재이름은 Object 입니다. 그리고 현재 Delegate 되어있는 Class 는 없다는걸 확인할 수 있습니다. 이제 Delegate 할 Class 를 찾으러 가볼까요.
아까 생성한 Class 의 header 파일을 보겠습니다. 오호라... ConvDelegator 라는게 이미 있군요. 저녀석을 쓸겁니다.
위의 화면에서 봤던 Object 라는 이름의 instance object 가 가리키는건 ConvDelegator 라고 지정을 해보겠습니다. 자 이제 instance object 는 interface 를 가질 수 있게 되었습니다 :D
Windows의 Delegate 재지정
이제부터는 기존에 지정되어있던 Delegator 에 대한 지정을 해제하고 새로만든 instance object 로 새로운 Delegate Mapping 을 진행해보겠습니다.
화면에 보이다시피 팔레트의 제일 위쪽에는 File's Owner 라는게 있습니다. 여기서 popup 메뉴를 불러보도록 하죠. 그러면 현재 xib 파일의 Delegate 로 지정된 instance object 를 알 수 있습니다. 오호.. 운좋게도 한화면에 같이 있었군요. 해당되는 객체 위에 Conv App Delegate 라는 문구가 표시되는게 보입니다.[1] 사실 잘 찾아보면 Conv App Delegate 라는 문구를 우리는 이미 봤을겁니다. 어디에 있냐면 바로 ConvAppDelegate.h 파일안에 있는 interface 부분이 바로 이 부분입니다. 이제 조금 감이 오기 시작하시나요?
일단 지금 진행하는 부분에서는 지정되어 있는 Delegate 를 해제하는것이 첫번째 과정이어야 하기때문에 popup 메뉴에 강조된것처럼 X 표시를 눌러서 지정되어있는 Delegate 를 삭제해줍니다.
Delegate 를 삭제했다면 새로 만들어진 instance object 를 다시 재지정해줘야겠죠. 화면대로 popup 메뉴에 있는 + 버튼을 마우스로 눌러서 아래쪽에 우리가 새로 만든 ConvDelegator instance object로 지정해줍니다. 이렇게 하면 이제 우리가 만든 instance object 가 현재 xib 파일의 Delegate 객체로 연결이 되는겁니다. 확인은 어떻게 하냐구요?
일단 아래쪽의 Assistant Editor 에 우리가 만든 Class 에 관련된 ConvDelegator.h 파일을 표시합니다. 그 다음 Windows 안에서 원하는 객체를 하나 마음속으로 고른후 Ctrl 버튼을 누르면서 아래쪽으로 휙! Drag 해주는거죠. 이야... 뭔가 표시가 나오네요? 참고로 제대로 Delegate 설정이 되어있지 않다면 Drag 했을때 삽입을 할 수 있는 위같은 화면을 볼 수 없습니다.
mouse 의 커서키를 떼면 다음과같은 Outlet 또는 Action 을 삽입할 수 있는 Help Window 가 뜹니다. 이렇게 까지 되면 내가만든 Class 를 Delegate 로 등록해서 사용할 수 있게 되겠죠?
위의 과정에서 잘 본것처럼 xib 파일은 별개로 동작하는것도 아니며 분명 필요한 만큼의 설정값을들 가지고 있다는 사실을 아실 수 있을겁니다. 지금 한 작업은 기본적으로는 전혀 필요가 없는 작업일 수 있겠습니다만, 어떤식으로 구조가 돌아가는지를 알기위해서는 필요한 과정이라 생각합니다. 이것으로 palate 와 interface builder, 그리고 Delegate 에 대한 부분이 조금은 명확해진것 같습니다.
Xcode 4 의 Interface Builder 에서 IBOutlet 코드 생성하기
자.. 이제 다시 원점으로 돌아와서 원래 해야할 일을 하도록 하겠습니다. (이 바로 위에서 했던 Delegate는 작업 안한걸로 할겁니다. 그러니 코드를 원복해주세요) Interface Builder 에서 만들어진 UI 를 실제 코드와 연결시킴으로서 나중에 UI 를 사용가능하게 만드는것이 이번부분에서 진행해야할 부분입니다.
일단 MainMenu.xib 파일을 선택해서 Interface Builder를 열도록 합니다. 그리고 화면의 아래쪽에는 Assistant Editor 를 준비해주시구요. 에디터에는 ConvAppDelegate.h 파일을 열어주세요. 자... 이제 진행해야할 부분은 간단합니다... 가볍게 끌어다 놓기만 하면 되는거죠 :D
Ctrl 키를 누른 상태에서 Windows 의 첫번째 TextField 를 Drag 해서 위의 스샷에서 보이는것처럼 아래쪽의 Assistant Editor 쪽으로 끌어다줍니다. 그럼 삽입이 가능한 부분에 저렇게 알아볼 수 있는 표식이 뜨게 됩니다. 이제 mouse 의 클릭을 해제해보도록 할까요?
오호 왼쪽에 웬 Help Window 가 떴습니다. IBOutlet 코드를 편하게 삽입하기위한 도움창 같은건데요. 우리는 Action 이 아닌 Outlet을 삽입할거라서 Connection 은 Outlet 으로 설정해줍니다(기본값이죠). 위의 TextFild 를 프로그램 코드에서 사용하기 위한 이름을 정할 수 있고 Storage Type 을 결정할 수 있습니다(이전의 Project builder 시절에는 없는 부분입니다만). 여기서 저는 Strong 을 선택하도록 하겠습니다. 아래의 코드에서 확인할 수 있겠지만 사실 이렇게 지정되는 값은 @property 로 지정됩니다. 좀 더 자세한 내용은 아래쪽에서 다루기로 하겠습니다.
입력값이 정리되면 Connect 버튼을 눌러서 코드를 삽입하도록 하겠습니다.
위와같은 방법으로 3개의 TextField 를 전부 삽입해주시면 되겠습니다. 그러면 코드는 다음과같은 모양이 될겁니다.
보이시나요? 이 코드의 모양을 잘 보고 TextField 를 입력할때 이름을 지정해주시는 부분을 참고해주시면 되겠습니다.
자 이제 Main Window 에 있는 Connect Button 을 연결하는걸로 하겠습니다. Button 은 Action 으로 연결할 것입니다.
TextField 를 Outlet 코드 삽입할때처럼 Ctrl 키를 눌러서 삽입을 원하는곳으로 Drag 합니다. 그럼 Outlet 을 연결할때와 같은 진행이 됩니다.
이번에 삽입할것은 Action 입니다. Connection 을 Action 으로 바꾸고 해당되는 객체를 연결할 이름을 입력합니다. 그다음 connect 버튼을 눌러줍니다.
이렇게 내용을 삽입하고나서 코드를 약간 정리하면 다음과같은 모양이 될겁니다.
새로 삽입한 코드를 쪼금 보기좋게 위쪽이랑 띄워놨습니다. 화면에 보이는것처럼 정리가 된다면 기본 코드는 성공입니다.
이번 부분에서 삽입된 코드는 다음과 같습니다.
@property (strong) IBOutlet NSTextField *rateField;
@property (strong) IBOutlet NSTextField *dollerField;
@property (strong) IBOutlet NSTextField *totalField;
- (IBAction)Convvert:(id)sender;
대체 Outlet 과 Action은 뭔가요?
Window의 입장에서 Outlet 은 출력. Action은 입력입니다. TextField 또는 Button 등은 값을 출력하고 입력할 수 있죠. 그렇기때문에 Outlet과 Action 양쪽 다 이용이 가능합니다. 굳이 흐름을 보자면 아래처럼 되겠군요.
코드에서 값을 Windows 로 보내는경우에는 Outlet, Windows 에서 코드로 값을 보내는경우는 Action 이라고 생각하면 됩니다. 그리 어렵지는 않습니다.
간단한 예를 들어보자면 Windows 에 배치한 객체가 Label 인 경우는 Outlet 을 삽입하려할때 아예 Outlet 만 선택할 수 있도록 되어있습니다. Label 은 입력을 받을 방법이 없기 때문이죠. 궁금하신 분들은 실험을 해보시는것도 괜찮을거같습니다 :D
storage는 대체 어떤 의미를 가지는건가요?
자세한 설명은 xcode 4.2 ARC retain, weak, strong 부분을 참고해주시기 바랍니다.
일단 위의 부분에서 일부만 발췌를 하면 다음과같은 부분이 있는걸 볼 수 있습니다.
▶ | strong은 그냥 retain과 같은 의미라고 생각하면 된다. 그러니까 기존에 property 선언시 사용했던 retain 키워드는 모두 strong으로 교체해 주면 된다. |
▶ | weak의 경우 조금 설명이 더 붙어있는데 일단 weak는 기존의 assign과 같은 개념이지만 dealloc 되었을 경우 대기 포인터로 남아있지 않고 바로 nil값으로 처리된다는 점이 다르다고 한다. |
▶ | 일단 깊숙한 부분에 대해서는 아직 이해가 부족한 만큼 그냥 retain -> strong, assign -> weak로 대체해서 사용하면 될 것 같다. |
오호.. 새로 추가된 부분인가봅니다. 사실 저는 그냥 strong 으로 사용하는게 편할거같기는 합니다만.... 객체의 해제라는 점에서는 weak 가 더 유용한거같군요 :D
간단하게 살펴보는 Objective-C 의 기호들
Objective-C 기호와 용어 정리 페이지를 참고해주시기 바랍니다.
Model Class::Converter Class 작성하기
자 이제 이 프로젝트에서 Model 의 역할을 하게될 Converter Class 를 작성해보도록 하겠습니다. (이제 스샷이 좀 줄겠군요. 만쉐!)
아까 윗부분에서 Diagram 그렸을때 여러개의 파일이 있는걸 보셨을거라 생각합니다. 굳이 다시 표시하는게 어렵지는 않으니 잠시 끌어내려와 볼까요?
이 Diagram 의 바로 위쪽에 아래와같은 정의를 내려놓은것도 기억하실지 모르겠습니다.
- Class 명은 Conv 로 정의한다
- Converter :: 통화량을 게산해서 값을 반환한다. Model 에 해당됨
- ConverterController :: Converter 객체와 AppDelegate 사이의 활동을 조정하는 클래스. Controller 에 해당됨
- ConvAppDelegate :: xib 파일에서 정의된 UI 객체들에 대한 동작을 정의하는 클래스. View 에 해당됨.
- xib 파일 :: AppDelegate 에 IBOut, 및 Action 으로 연결되는 사용자 UI
자 그럼 Converter 를 만든다는건 데이터를 처리하는 Model 을 작성한다는 의미가 되겠습니다. 위쪽에서 MVC 에 대한 설명을 했을때 각 역할에 대한 설명을 한걸 기억하실겁니다. Controller 는 View 에서 데이터를 받아서 그걸 어딘가의 Model 로 전달하는 역할만 하는거죠. 그렇다면 Model 에서 받은 데이터에 대한 처리를 다 해서 결과를 돌려주는 부분까지의 작업을 가지고 가야하는걸 쉽게 짐작할 수 있게 됩니다.
이제부터 원래 문서에 있는 내용을 기초로 Model 에 해당하는 Converter Class 를 작성하도록 하겠습니다. Converter Class 를 작업한다면 당연히 Converter.* 파일에서 작업을 진행해야겠죠 :D
파일이 있을리가 없으니 위에서 설명한 요령대로 Converter Class 파일을 추가해서 작업을 진행할 준비를 합니다. 작업하는김에 Controller Class 의 작업에 사용할 Class 까지 같이 생성하는걸로 하겠습니다. 제대로 파일이 생성이 되었다면 Navigator area 에 다음과같은 내용이 표시되어야 합니다.
작업을 시작하도록 할까요?
Converter Class 의 기본골격
Converter.h 파일을 열어서 코드를 삽입할 준비를 합니다. 기본적으로 다음과같은 내용이 Class 생성시 이미 들어가 있습니다.
#import <Foundataion/Foundation.h>
@interface Converter : NSObject
@end
Converter Class 에 Method 추가하기
이제 기존의 코드를 다음과같이 수정해보겠습니다.
#import <Cocoa/Cocoa.h>
@interface Converter : NSObject
{
}
+ (float)convertAmount:(float)amt atRate:(float)rate;
@end
수정된 코드에서는 2가지가 크게 변경되었습니다.
- import 부분에서 Foundation 이 Cocoa 로 변경되었습니다
- convertAmount 인스턴스 메서드가 추가되었습니다.
-(minus)기호 로 되어있는 부분은 instance method, +(plus) 기호로 선언되는 부분은 Class method 입니다. 두개간의 차이는 여기 링크를 보면 좀 더 명확하게 알 수 있습니다. 여기서는 간단하게만 설명하기로 하죠.
Smalltalk 에서 유산을 받은 Objective-C 는 두가지 타입의 method 를 가지고 있습니다. instance 와 class 가 대상이 되는 타입이 되는데요...... 이 두가지는 개념상 어떤 차이가 있을까요?
- instance method :: instance method 는 Class 를 이용해서 객체(Object)를 생성한 후에 사용할 수 있는 메서드
- class method :: Class method 는 Class 를 이용해서 객체를 생성하지 않고도 사용할 수 있는 메서드
일단 위의 코드에서 추가한 메서드는 class 메서드 입니다. 때문에 추가한 메서드는 객체 생성없이 바로 사용할 수 있습니다.
별도로 내부에 instance 변수에 접근할 필요없이 계산결과만 반환하기 때문에 굳이 instance 메서드를 사용해야할 필요는 없습니다.
새로 선언된 메서드에 대한 내용
이제 선언된 부분에 대한 내용을 살펴보도록 하겠습니다. 선언부는 다음과같이 표현할 수 있습니다.
▶ | convertAmount:atRate: |
이 선언의 의미를 살펴보면 다음과 같습니다.
- convertAmount 에서 인자를 취합니다. 인자는 Float 형.
- atRate 에서 인자를 취합니다. 인자는 Float 형
- Float 타입으로 결과를 변환합니다.
이제 메서드의 interface를 선언했으니 실제 메서드의 동작을 정의하도록 하겠습니다.
class 메서드의 동작 구현을 위한 @implementation 부분 확인하기
위에서 선언한 메서드의 interface 에 따라 선언한 메서드의 동작을 구현해보도록 하겠습니다.
일단 Converter.m 파일을 편집기로 열도록 하겠습니다. 그러면 아래와같이 되어있는 기본틀을 확인할 수 있습니다.
#import "Converter.h"
@implementation Converter
@end
이제부터 여기에 내용을 채워넣기로 하겠습니다.
class 메서드의 동작 구현
위에서 본 @implementation 코드 부분을 다음과같이 변경합니다.
#import "Converter.h"
@implementation Converter
+ (float)convertAmount:(float)amt atRate:(float)rate
{
return (amt*rate);
}
@end
잘 보시면 별로 어려울만한 부분은 없습니다. 입력받은 amt 와 rate 를 곱해서 반환하는게 작업내용의 전부입니다.
View Class::사용자 Interface 에 대한 내용구현
이미 우리는 위쪽에서 xib 파일의 Window 에 있는 Currency Button 에 대한 Action 을 정의한것을 기억하실겁니다. 이제 그 내용에 살을 좀 붙여보도록 하겠습니다.
원문에서는 ConverterController Class 가 View(xib파일)에 바로 연결되는 구조였기때문에 지금부터 나오는 코드는 원문과 100% 동일하지는 않게 될거같습니다.
기존 코드에 대한 분석
일단 Action 에 대해서 언급해놓은 원문의 코드를 보도록 하겠습니다.
- (IBAction)convert:(id)sender
{
float rate, amt, total;
amt = [dollerField floatValue];
rate = [rateField floatValue];
total = [converter convertAmount:amt atRate:rate];
[totalField setFloatValue:total];
[rateField selectText:self];
}
물론 위의 코드를 사용하기 위해서는 Converter.h 파일을 위의 파일의 상단 부분에서 #import 해줘야 합니다.
자.. 이제 원문에서 작성된 코드를 분석해야 필요한 부분을 바꿔서 쓸 수가 있겠죠? 원문에서 위의 내용은 ConverterController.m 파일의 @implementation 부분에 선언되어 있습니다.
- 일단 rate, amt, total 이라는 float 형 변수를 선언합니다. 전형적인 C Language Style 임.
- amt 라는 변수에 IBOutlet 으로 이미 지정한 dollerField 객체의 floatValue 메서드를 실행한 결과를 받아서 넣는다.
- rate 라는 변수에 IBOutlet 으로 이미 지정한 rateField 객체의 floatValue 메서드를 실행한 결과를 받아서 넣는다.
- total 이라는 변수에 위에서 선언한 클래스인 converter 클래스의 instance 메서드 convertAmount:atRate: 를 실행한 결과를 넣는다. 메서드의 인수로는 amt 와 rate 를 사용한다.
- IBOutlet 으로 이미 선언해놓은 totalField 객체에 setFloatValue: 메서드로 total 변수를 인수로 삼아 값을 집어넣는다.
- rateField 객체에 selectText: 메서드를 self 를 이용해서 rateField 객체 스스로를 인수로 삼아 실행한다.
대략 코드의 내용은 이와같이 나오는거같고.... 이제부터 해야할것은 이 구조를 어떻게 바꿔야 의도한바의 MVC 로 변경하고 코드를 수정해야하는지에 대한 plan을 세워야 하겠죠.
바꿀 코드의 구조는 어떻게 되어야 할까요?
MVC 에 의하면 View 에서 Data를 얻고 다시 View 로 보내는 작업을 Controller 에서 해야한다고 되어있습니다. 일단 위쪽의 Converter Class 에서 Model 에 대한 부분은 작업이 이미 된 상태이니 지금부터는 Controller(CurrencyController Class) 와 View(ConvAppDelegate Class) 에 대해서만 살펴보기로 하겠습니다.
Class Struct(Controller)
- View 에서 Action이 호출되었을때 연산을 진행하고 값을 처리하는 메서드
Class Struct(View)
- 다른곳에서 호출이 있을때 각 객체의 값을 반환하는 메서드
- 다른곳에서 값이 넘어왔을때 해당되는 객채의 값을 변환하는 메서드
- Action 이 일어나는경우 Controller Class 를 호출하는 메서드
View Class 의 구현
위에서 다룬대로 구조를 바꾸려면 일단 View Class 부터 바꿔야 합니다. 새로 언급한 3가지 요소중 Action 관련된것을 제외한 나머지 메서드들을 먼저 구현해보기로 하겠습니다. 일단 interface 부터 구현을 하는게 맞겠죠? ConvAppDelegate.h 파일에 새로운 코드를 선언해보기로 하겠습니다.
TextField 의 값을 얻어와서 반환하는 메서드 구현
각 파일에 아래와 같은 내용을 작성해 넣도록 하겠습니다. (위치는 눈치껏.. 아시죠?)
//ConvAppDelegate.h file
- (float)getDollerField;
- (float)getRateField;
//ConvAppDelegate.m file
- (float)getDollerField
{
return [_dollerField floatValue];
}
- (float)getRateField
{
return [_rateField floatValue];
}
위의 2개의 메서드는 요청에 따라 해당되는 TextField 의 값을 가져와서 반환하는 일만 진행합니다.
Convert 버튼을 눌렀을때에 동작을 하는 내용에 대한 메서드 구현
- (IBAction)Convert:(id)sender; 메서드(이미 위에서 이 메서드를 추가했었죠) 에 대한 내용을 구현해보겠습니다
//ConvAppDelegate.m file
- (IBAction)convert:(id)sender
{
float total;
CurrencyController * CalcObject = [CurrencyController new]
total = [CalcObject calculate:self];
[_totalField setFloatValue:total];
[_rateField selectText:self];
}
위의 Action 메서드에 대한 구현의 내용은 CurrencyController 클래스의 calculate 라는 메서드를 실행해서 그 결과값을 받은다음 결과값을 출력해야할 곳에 출력하는 일을 진행합니다.
위에서 사용된 new 라는 메서드(메시지)는 alloc 과 init 를 한번에 동작시키는걸로 이해하시면 되겠습니다. 원래부터 Objective-C 에 있던 기능은 아닙니다만.. 추후에 추가된것으로 보입니다.
이 내용을 동작시키기 위해서는 ConvAppDelegate.m 파일의 상단에 #import "CurrencyController.h" 를 넣어줘야 하는걸 잊지 말아주세요.
위의 부분에서는 정확하게 한곳이 중요합니다.
total = [CurrencyController calculate:self];
일단 저 부분이 왜 중요하냐면 calculate 메서드에서 연산을 진행하기 위해 값을 얻어오려면 생성되어있는 instance 에서 값을 얻어와야 합니다. 그런데 c 나 c++ 의 경우는 생성된 instance 의 Pointer 값을 넘기게 되는데요 여기서는 현재 UI windows 를 나타내는 self 를 인자로 던져줍니다. 그럼 이후 calculate 메서드에서는 이걸 전달받아서 객체(instance)의 instance 메서드를 실행할 수 있게 됩니다.
자 그럼 이제 실제로 계산작업의 프로세스를 진행할 CurrencyController(Controller Class) 클래스의 메서드를 구현해보기로 하겠습니다. 현재 Convert Action 은 calcurate 라는 메서드를 메시지로 사용하기때문에 관련된 메서드를 새로 구현해주어야 합니다.
Controller Class::CurrencyController 의 내용구현
CurrencyController 클래스의 내부에서 사용될 calculate 메서드의 내부동작에서의 순서는 다음과 같습니다.
- getDollerField 를 이용해서 dollerField 의 내용을 가져온다
- getRateField 를 이용해서 rateField 의 내용을 가져온다
- 가져온 내용을 Converter Class 의 convertAmount:atRate: 메서드에 대입해서 결과를 받아낸다
- 받아낸 결과값을 반환한다.
위의 내용을 기초로 이제 각 파일에 메서드를 작성해 보겠습니다.
//CurrencyController.h
- (float)calculate:(ConvAppDelegate*)MainWindow;
//CurrencyController.m
- (float)calculate:(ConvAppDelegate*)MainWindow
{
float amount, rate, result;
amount = [MainWindow getDollerField];
rate = [MainWindow getRateField];
result = [Converter convertAmount:amount atRate:rate];
return result
}
CurrencyController.h 파일의 상단에는 다음의 한 줄이 추가되어야 합니다. Class 에 대한 정의가 필요하기 때문이죠.
- #import ConvAppDelegate.h
CurrencyController.m 파일의 상단에는 다음의 한 줄이 추가되어야 합니다.
- #import Converter.h
CurrencyController 클래스의 calculate 메서드 내용분석
내용은 그리 복잡하지 않습니다. View class 에서 값을 가져온다음 그 값을 Converter 클래스를 이용해서 계산하고 계산된 결과값을 calculate 메서드를 호출한 객체에게 반환합니다.
조금 주의할것은 위쪽에서 설명을 이미 한번 했습니다만.. 아래의 부분입니다.
//CurrencyController.h
#import ConvAppDelegate.h
- (float)calculate:(ConvAppDelegate*)MainWindow;
위처럼 UI의 Delegate 를 담당하는 Class를 import 한다음 receive 되는 객체의 Type Casting을 정확하게 해주면 됩니다.
객체의 타입을 정확하게 모르겠는 경우는 Action 부분에서 NSLog([self className]); 정도로 xcode의 log 에서 확인해주시면 되겠습니다.
자 이제 만들어진 프로그램을 실행해볼까요?
완성된 프로그램의 실행
이렇게 간단한 예제 프로그램의 제작이 끝났습니다. 물론 이것말고도 할 수 있는 작업이야 많겠습니다만.... 나름 xcode의 기본에 대해서 충실하게 배울 수 있었던 기회였네요. (사실 이런방식으로 설명한 책이 따로 없기도 하고...)
모쪼록 읽으시는 분들께도 좋은 내용이 되었으면 좋겠습니다.
첨부파일
참고자료
한글자료
- Objective-C 2.0 관련강의
- Objective C Design Pattern 관련 한글자료
- XCode4.2에서 스토리보드를 사용해보자!!
- Xcode 4 PR2 개선점
- Objective-C 2.0 개요 from ADC
- Protocol(델리게이트)
- Xcode4에서 기존 프로젝트에 ARC(Automatic Reference Counting) 적용시키는 방법
- "Objective-C" NSArray 사용법 예제
- NSMutableArray, NSArray, 배열의생성과요소접근, 배열
참고자료::git와 xcode
git 와 redmine 을 사용하는경우 git의 작업은 ssh 를 이용하게 되는데 이 경우 ssh 의 key를 이용한 인증을 진행하게 된다. xcode 에서 repository 에 접근하려는경우 ssh key(private)를 mac os X 에서 로딩해주어야 하는데 다음과같이 하면 부팅시마다 키를 ssh-add 로 매번 로딩하지 않아도 된다
# 터미널에서
ssh-add -K /path/to/private_SSH_key
참 편리한 방법이다. 경로명을 상대경로명으로 적어도 되는지는 모르겠으나 굳이 모험을 하고 싶지는 않다.
영문자료
Notes
- ↑ 제가 헷갈렸던 부분인데 이전의 자료에서는 interface builder 에서 그냥 UI 를 설계한다음 이 과정이 필요했기때문에 별도 설명이 있었는데 Xcode 4 에서는 보시다시피 이미 프로젝트 생성시 xib 파일을 Delegate 해줄 instance object 를 미리 만들어줍니다. 사실 지금 하는 과정이 딱히 필요가 없기는 하죠. 다만 공부하는셈치고 나머지과정을 진행해보면 이런구조구나.. 라는걸 아실 수 있을겁니다