Jazz Scale을 배워 보자!! 음악

드디어 지난 주말 등록신청한 어플이 통과되어 판매가 시작되었습니다.

현재 팟게이트 인기순위 50위권에 진입했고 iPad 어플스토어에 Music 카테고리엔 7위를 유지하고 있네요.

이름하야 Jazz Scale!!!이라는 어플입니다.

우선은 프로그래밍적인것 보다는 음악적인 이야기 부터 시작해 볼께요.

어플의 목적은 바로 재즈를 공부하고 싶어 하는 분들, 혹은 시작하신 분들, 혹은 연주 하고 계신분들을 도와드리기 위한 어플입니다.

재즈.. 어려운 음악이다..라고들 생각하시는데요.. 쉽지는 않지만 그리 어렵지도 않을 수 있습니다.

우선 재즈에서 가장 매혹적인 요소는 즉흥연주!!!

내맘대로 내삘대로 나의 마음을, 혹은 영혼을 연주 할 수 있다니!!

클래식연주처럼 음표하나 틀렸다고 손등을 자로 맞지 않아도 된다니!!

그렇습니다. 바로 자유로운 즉흥연주가 재즈의 매력이겠죠.

하지만 제가 음악 전공을 해오며 가장 뼈저리게 틀렸다고 생각하는 말은 바로

"음악은 자유롭다" 라는 말인 것 같아요.

죄송하지만 음악엔 분명히 "틀" 이 있습니다. "법칙"과 "굴레" 라고도 할 수 있겠네요.

물론 진짜 손가락 가는데로 막 연주하는 프리재즈같은 장르도 있겠지만 기본적으로 다른 사람의 귀를 즐겁게 하려면

주어진 "틀"과 "법칙" "굴레"안에서 놀아야 합니다.

"아니야!! 그럴리 없어!! 나의 음악은 틀이 없는 자유로운 영혼정도는 아니지만 프리한 소울의 음악을 할꺼야!"

라고 생각하시는 분이 계실지는 있을지 모르겠지만...

중요한 점은 바로 "틀"을 정확히 알고 이해해야 아름답게 깰 수 있다는 것 입니다.

그렇다면 즉흥 연주의 "틀"은 과연 무엇일까요? 자신이 연주하고 싶은 "재즈적인" 멜로디는 어디서 부터 나오는 것일까요?

그것은 바로 "스케일"입니다.

우선 재즈 스텐다드의 악보를 살펴 보도록 하죠.

 제가 제일 좋아하는 곡중에 하나인 All the Things You are 입니다.


일단 콩나물 음표들은 원곡의 멜로디 입니다. 이부분을 Head.. 헤드라고 합니다.

보통 연주를 시작하면 이 헤드를 손상시키지 않고 최소한의 멜로디 페이크정도만 넣어서 연주를 한번 하고 시작하고

끝나기 전에도 한번 훑어 주는게 통상적인 예의랍니다.

그래야 시작할때 "아!! 이노래!!" 하고 시작하고 끝날때 "아!!드디어 끝났구나..하암.."이라고 할 수 있으니까요

그리고 마디마다 위에 코드가 쓰여있는데요. F-7  Bb-7  Eb7 Abmaj7 이렇게 써있죠?

이것들이 곡의 골격, 또는 즉흥연주를 어떻게 해야 할 것인가에 대한 "이정표" 되겠습니다.

물론 원곡의 코드를 쪼개고쪼개고 대체하고 대체해서 다른 곡처럼 편곡하기가 일쑤 입니다만

일단 기초적인 단계에선 욕심을 버리고 시작합니다.

자 그럼 이 코드들에 매치가 되는 스케일이란 놈들이 있죠.

스케일은 쉽게 말하면 "음계" 인데요. 우리가 알고 있는 대표적인 음계로는 즐거운 장음계 (메이져..아이오니안이라고도 합니다)

"도레미파솔라시도"..

혹은 슬픈 단음계 (마이너)..(자연단음계로 갈께요)

"도레미b파솔라b시b도"~

가 있겠습니다. 이러한 대표음계를 어디서 부터 시작하느냐에 따라서 또 새로운 스케일로 분류가 되는데요.

예를 들면 장음계 "도레미파솔라시도"를 두번째 음인 "레" 부터 시작을 하면 "레미파솔라시도레" 가 되겠죠?

이 음계의 이름은 "도리안" 되겠습니다. 이런식으로 파생되는 스케일의 수는 약 2백개 정도가 됩니다.

이걸 다 외우고 손가락에 익히고 쓰고 싶을때 착착 꺼내 쓸 수 있어야 비로소 재즈 연주자가 될 수 있습니다.

무섭죠 어흥!

은(는) 훼이크고...

자주 쓰는 스케일순으로 점점 연습하다보면 그냥 머리속의 멜로디가 알아서 나오는 경우가 생긴다..카더라...

자 그럼 이제 어디서 어떤 스케일을 써야 하는지 알아보도록 합시다.

All The Things You Are의 첫 마디부터 살펴 볼께요.

F-7이라고 써있군요...헤드의 음(멜로디)은 Ab이네요...

수많은 스케일들중에 -7 (마이너 7) 코드에 재즈스럽게 아름답게 어울리는 스케일은 몇개가 있을까요?

통상적으로 마이너7에 쓰이는 스케일은 6개 입니다.

"도리안", "마이너 펜타토닉" "비밥 마이너" "블루스" "디미니쉬드 (온음간격부터 시작하는..)" "비밥스케일"

이정도 인데요. 이 6개의 스케일이 모두 12키를 가지고 있겠죠? C-7 이라면 C도리안 스케일인

"도레미b파솔라시b도" 가 되겠고 D-7이라면 D도리안 스케일인 "레미파솔라시도레"가 되겠습니다.

이런식으로 하여 -7키에 해당되는 스케일은 6곱하기 12..는 72개군요..그럼 자..72개 스케일을 다 연습해 봅시다..

가아니라.. 일단 맘에 드는 스케일을 하나 골라 보도록 하죠..

Blues... 맘에 드네요.. 그럼 F키의 blues 스케일..

"파 라b 시b 시(네츄럴) 도 미b 파"~ 가 되겠죠..연습합니다..

음..그다음 마디는 Bb-7이군요...또 마이너7 코드!!

그럼 기왕 이렇게 한거 Bb 블루스로 통일!

"시b 레b 미b 미(네추럴) 파 라b 시b"~~ 연습합니다..

오오 그다음 코드는 Eb7..7th 코드에 주로 쓰이는 스케일은 Dominant 7th, 메이저 펜타토닉, 비밥, 블루스.. 4가지 입니다.

기왕 블루스 간거 또 블루스로...Eb블루스 스케일을 보면..

"미b 솔b 라b 라(네추럴) 시b 레b 미b"~~~~

이렇게 다음 마디까지 스케일을 외우고 메트로놈/ 혹은 반주에 맞춰 4마디 스케일을 상행으로 하행으로 상하행으로 연주해 보면

쭈르륵 올라갔다 쭈르륵 내려오기만 해도 뭔가 쟂으 스러운데??라는 느낌이 드시길 바랍니다. ㅎㅎ;

손에 스케일이 익으시면 다시 한번 헤드를 연주해 보세요..

아까의 스케일들과 오버렙 되면서 어떻게 변형이 될지 좀 아이디어가 떠오르나요??

이런식의 연습을 도와주기 위한 어플이 바로 Jazz Scale입니다.(무료!)

http://itunes.apple.com/kr/app/jazz-scale/id463194964?mt=8

혹은 앱스토에서 Jazz Scale이라고 검색해 주세요 ^^


보시다 시피 직접 머리아프게 전조해서 연습할 필요 없이 b #버튼을 눌러 전조된 악보를 불러올 수 있고

메트로놈 기능도 첨가되어 있습니다. (처음 몇박자는 좀 저는 수도 있어요.. ㅠㅠ)

뭐 아주 기초적인 간단한 어플이지만 연습하기 좋은 툴로서 많이 사용되었스면 좋겠다는 마음에 공짜로 풀었답니다.

(가끔 광고는 좀 클릭을.... 굽신굽신..;;)


Xcode에서 Sample Code 열때 트러블 슈팅. SDK Anatomy

이전 글에서의 MoveMe같은 오픈 소스를 불러와 Xcode에서 시뮬레이터를 이용해 돌려볼때 일어날 수 있는 에러에 대한 트러블 슈팅입니다.

문제 1. Xcode로 파일을 열었을때 Frameworks의 폴더 아래 있는 .frameworks 들이 빨간색으로 뜹니다.


해결 : /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.1.3.sdk/System/Library 경로에 있는 framework폴더들을 복사해서 해당 오픈소스가 있는 폴더에 에러가 나는 경로를 맞추어 넣어 주면 검은색으로 활성화가 됩니다.

넣어야 할 폴더의 경로알아 보는 방법: 빨간글씨로 뜨는 프레임웤을 우클릭하여 Get info를 클릭하여 경로를 확인합니다.

문제 2 : Active SDK가 비활성화되어 있어요!! Build and Run을 눌러도 시뮬레이터 실행이 안되요!

해결 : Xcode에서 Overview 영역에서 MoveMe파일을 우클릭한 후 Get info를 선택하여 Build 텝에 있는 Base SDK항목을 알맞은 버전의 시뮬레이터로 바꾸어 줍니다.

그리고 Build and Run을 하면 됩니다.

끝!


iPhone Apps 만들기! 2편 SDK Anatomy

Finishing the Application!!

 이전의 섹션에서 무브미 어플의 유저인터페이스와 이벤트들의 응답을 통해 무브미 어플리케이션이 어떻게 시작 되어지는지 알아보았습니다. 게다가 이러한 것들 이외에도 어플을 개발하고 디바이스에서 실행하기 이전에 고려되어질 작은 디테일들이 있습니다.
최종 단계중의 한가지는 어플리케이션의 정보를 Info.plist라는 프라퍼티 리스트 파일 입니다. 이것은 어플리케이션의 기본적인 정보에 대해 시스템에게 알리는 XML파일입니다. Xcode는 기본적으로 디폴트 버전의 파일을 제공합니다. 개발자는 시스템이 알아야 할 어플에 대한 정보를 더욱 자세하게 제공할 수 있습니다. 예를 들어 어플의 버전 정보, 어플을 지원하는 URL정보, launch image, 시스템 상태 바의 스타일등이 있습니다.

다음은 무브미 어플의 Info.plist파일을 보여줍니다. 파일은 유저의 홈스크린에 나타날 이미지 파일과 실행명등의 정보를 제공합니다. 무브미 어플은 풀스크린 어플이기 때문에 이것은 또한 UIStatusBarHidden키와 그것의 true벨류를 포함하고 있습니다. 이 키를 True로 설정함으로서 시스템이 어플이 돌아가는 동안 UI Status Bar (시계, 안테나, 와이파이상태, 베터리 잔량을 표시해 주는 상단의 바)를 보여 주지 않습니다.

NOTE: 개발자는 어플의 Info.plist 파일을 위의 화면과 같이 보여지는 XML컨텐츠를 보여주는 TextEdit나 파일의 키와 테이블안의 벨류를 보여주는 Property List Editor를 사용하여 작성할하거나 수정할수 있습니다. Xcode는 또한 이런 정보를 보여주는 어플리케이션 타겟을 위한 인포메이션 윈도우를 제공합니다. 이 윈도우를 보기위해선 어플의 타겟을 선택하고 Choose File > Get Info를 선택하세요 프라퍼티 텝이 전부는 아니지만 info.plist파일에 있는 프라퍼티들을 보여 줍니다.

Info.plist파일의 설정에 대해 더 자세히 알고 싶다면 iOS Application Programming Guide의 "The Information Property List"항목을 참조 하세요.

Taking Your Applications Further!

이하 내용은 별로 중요한 내용은 아니고 대략적인 추가 기능들에 대한 이야기 입니다.

Tracking Orientation and Motion Using the Accelerometers

기기 내의 Accelerometers를 이용하여 기기의 위치의 변화를 좌표로 인지하여 적용시킵니다.
이를 통해 기계를 가로로 들었는지 세로로 들었는지 알 수 있고 그럼에 따라 화면을 가로모드 세로모드로 바꿔 줄 수 있습니다. 이러한 작업은 UIViewController 클래스를 사용하여 구현할 수 있습니다.

악셀러로메터를 통한 데이터를 직접 사용 하고 싶다면 UIKit의 UIAccelerometer 오브젝트를 통해 데이터를 이용 할 수 있습니다. UIAccelerometer오브젝트는 현재 기기의 위치의 벨류를 리포트 해줍니다. 또한 기기를 흔들었는지 어쨌는지 등의 정보도 받을 수 있습니다. (예를 들면 아이팟 기능중에 흔들면 셔플기능 뭐 이딴것들..)
더 많은 정보를 위해 iOS Application Programming Guide내에 있는 "Accessing Accelerometer Events"를 확인하세요.

Accessing the User's Contacts

만약 Whatsapp이나 카카오 같은 어플을 만들고 싶다면 기기안의 연락처에 접근해야 할 것입니다.
자세한 사항은 Address Book Framework Reference for iOSAddress Book UI Framework Reference for iOS를 참조하세요.

Getting the User's Current Location

오빠뭐해등등의 위치 추적이나 GPS를 활용한 어플을 만들 수도 있습니다 iOS Application Programming Guide의 "Getting the User's Current Location"을 참조 하세요.

Playing Audio and Video

iOS 는 Core Audio 와 OpenAL frameworks를 통해 오디오 기능을 어플리케이션에 제공하며 Media Player framework를 통해 비디오 재생도 제공합니다. 코어 오디오는 재생, 녹음, 파싱 스트리밍 오디오와 다양한 사운드등을 위해 사용 되어 집니다. 이를 통해 다양한 단순한 사운드 이펙트를 사용할 수 있거나 멀티체널 오디오, 사운드 믹스와 오디오 필드의 포지션등을 활용할 수 있고 또한 진동기능까지 활용 할수 있습니다. 만약 당신이 게임 디벨로퍼라면 이미OpenAL에데해 알고 있을 것 입니다.

미디어 플레이어 프레임워크는 풀스크린 비디오 파일을 재생하기 위해 필요 합니다. 이 프레임워크는 많은 스텐다드 무비 파일 포멧을 재생하고 플레이백 환경을 조정하며 디스플레이를 조정할 수 있게 해 줍니다. 게임 디벨로퍼는 아마 프레임워크를 오프닝이나 중간중간의 에피소드 재생등을 위해 활용 할 수 있을 것 입니다.

더 많은 미디어 테크놀로지에 대해 알고 싶다면 Multimedia Programming Guide를 참조 하세요.

Taking Pictures with the Built-in Camera

카메라 어플리케이션으로 카메라를 활용한 어플을 만들 수 있습니다. 또한 비록 아이팟터치는 카메라를 가지고 있지 않지만 사용자가 업로드 시킨 사진들을 포토 라이브러리에서 꺼내 사용 할 수 있습니다. UIKit 프레임워크에 UIImagePickerController클래스를 활용하세요.

더 자세한 사용법을 위해 iOS Application Programming Guide안의 "Taking Pictures with the Camera"와 iOS Application Programming Guide안의 "Picking a Photo from the Photo Library"를 참조 하세요. ''

끝!!

iPhone Apps 만들기! 1편 SDK Anatomy

높은 수준에 오른다면, iPhone Apps 개발과정은 같은 개발 툴과 같은 기본 라이브러리를 사용하기 때문에 Mac OS X apps를 만드는 제작 과정과 흡사 합니다.  그러나! 이러한 유사성이 있음에도 분명히 둘 사이에는 다른 점이 있습니다. 그 이유는 iPhone은 일반 데스크 탑과 다른 목적을 띄고 있고, (기본적으로 모바일 디바이스이며 전화기라는 점)매우 다른 디자인적 특성을 가지고 있기 때문입니다.
또한 아이폰과 아이패드, 아이팟의 터치스크린의 제한적 사이즈를 고려하여 정말로 유저가 필요한 정보들을 어떻게 잘 정돈할 것인가에 집중하여 디자인 하여야 할 것입니다.

iOS는 유저가 데스크탑 어플리케이션에서는 할 수 없는 작업(interact)들을 아이폰, 아이팟, 아이패드를 통해 구현할 수 있도록 지원해 줍니다. 예를들어 멀티 터치 인터페이스는 여러 손가락을 이용한 인식작용과 복잡한 입력을 쉽게 할 수 있도록 도와줍니다. 또한 accelerometers와 같은 하드웨어 탑재 기능은 비록 몇몇 데스크탑 시스템이 탑재 하고 있긴 하지만 iOS상에서 더욱 확장적으로 사용될 수 있습니다. 이러한 iOS만의 특수한 기능들을 잘 이해함으로써 유저를 위해 적절한 기능들을 활용함으로서 더욱 좋은 apps를 만들 수 있을 것 입니다.

다음은 MoveMe라는 샘플 어플리케이션을 통해 앞서 말한 기능들을 둘러 보도록 하겠습니다. MoveMe어플은 아이폰 어플에서 전형적으로 사용되는 다음과 같은 기능들을 보여줄 것입니다.
  •  어플 시작하기
  •  윈도우 보여주기
  •  커스텀 콘텐츠 그리기
  •  터치 이벤트 처리
  •  애니메이션 활용
Figure 1은 MoveMe 어플의 인터페이스 입니다. Welcome버튼을 터치하면 버튼을 진동하고 손가락 가운데 위치로 버튼을 옮겨오는 애니메이션을 작동시킵니다. 손가락을 스크린 위에서 드래그 하면 버튼은 손가락을 따라오게 됩니다. 손가락을 스크린에서 떼면 또다른 애니매이션을 이용하여 버튼은 원래의 자리로 돌아가게 됩니다. 버튼의 바깥 쪽을 더블 텝핑 하게 되면 버튼의 인삿말이 다른 나라의 언어로 바뀌게 됩니다.

 Figure1 The MoveMe application window









































MoveMe의 샘플 코드를 다운 받으시려면 클릭! 하세요 (apple 공식 샘플 코드입니다.)
만약 Objective-C에 익숙하지 않으신분이라면 이전 포스팅인 Object-C 배우기: 초급 을 읽어보세요.

MoveMe 샘플 프로젝트를 해부해 보자!!

다운받은 MoveMe 샘플 코드는 어플리케이션을 만들고 실행하기위한 서포트 파일과 소스코드들을 제공합니다.

MoveMe.xcodeproj 파일을 Xcode로 열게 되면 다음과 같은 화면을 보실수 있습니다.


Building the MoveMe Application!!


무브미 어플을 빌드하고 시뮬레이터에서 돌리기 위해 다음의 단계를 따라하세요.

1. MoveMe.xcodeproj 파일을 Xcode에서 여세요.

2. 프로젝트 툴바에서 Actice SDK 메뉴에 있는 simulator 옵션이 선택되었는지 확인하세요. (Active SDK 매뉴가 툴바에 나타나지 않으면 Project > Set Active SDK > Simulator.의 경로를 사용하세요)

3. Build > Build 에서 Go 를 선택하세요. 혹은 그냥 툴바에서 build와 go 버튼을 누르세요.

어플리케이션 빌딩이 끝나면 Xcode는 iOS Simulator에서 파일을 로드하고 실행시킬 것 입니다. 마우스를 이용하여 Welcome 버튼을 클릭하고 드래그하시면서 어플이 어떻게 작동하는지 확인 할 수 있습니다. 만약 사용할수 있는 디바이스가 있다면 디바이스 상에서도 확인하실 수 있습니다. 그 방법은 iOS Development Guide를 참조 하세요

A Word About Memory Management
!!

iOS는 기본적으로 객체지향 시스템입니다. 그럼으로 대부분의 우리가 할당하는 메모리는 Object-C 오브젝트의 폼 안에 있습니다. iOS는 오브젝트에 의해 점유되는 메모리가 자유로이 쓸수 있도록 안전한지 알기 위해 reference counting schem을 사용합니다. 처음으로 오프젝트를 생성시킬때 그것은 레퍼런스 카운트를 1증가 시킵니다. 클라이언트는 오브젝트를 유지할수 있는지를 확인하는데서 부터 시작합니다.  만약 클라이언트가 오브젝트를 유지한다면 클라이언트는 그것이 더이상 필요하지 않을때 반듯이 릴리즈 해야 합니다. 오브젝트를 릴리징 하는것은 그것의 레퍼런스 카운트를 1 감소 시킵니다. 오프젝트의 레퍼런스 카운트가 0이 되었을때 시스템은 자동적으로 오브젝트의 메모리를 환원합니다.

** iOS는 Mac OS X v10.5 이상에서의 특징인 가비지 컬렉션을 사용하는 메모리 관리를 지원하지 않습니다. **

만약 오브젝트와 연관이 없는 메머리의 제네릭 블럭들을 할당하고 싶다면 기본 malloc 라이브러리를 불러와 사용할 수 있습니다. malloc을 사용하는 어떠한 메모리 할당의 경우 최후에는 개발자기 직접 free 라고 불리는 기능을 이용하여 메모리를 릴리즈 시켜주어야 할 의무가 있습니다.

개발자가 어떻게 메모리를 할당하던지 간에 메모리 관리를 overall하는 것은 중요합니다. 비록 iOS가 가상 메모리 시스템을 가지고 있지만 그것은 swap 파일을 사용하지 않습니다.  (Swap file이란? 컴퓨터의 실제 메모리, 즉 램의 가상메모리 확장으로 사용되는 하드디스크상의 한 공간이다. 스왑파일을 가짐으로써, 컴퓨터 운영체계는 실제보다 더 많은 량의 램을 가지고 있는 것 처럼 동작할 수 있다. 즉 가장 오랫동안 저장되었던 램상의 파일이 새로운 파일을 위하여 하드디스크에 스왑파일로서 저장되었다 필요에 의해 불려지는 것이다. 페이징 이라고도 불림.) 이 말인 즉 코드페이지는 필요에 의해 가득 채워 질 수 있지만 동시에, 어플리케이션의 데이타는 반드시 메모리에 맞아 떨어져야 한다는 말이다. (여분이 없으니 메모리 관리를 잘하라는 말..;;). 시스템은 메모리의 여유공간을 모니터 하고 있다가 어플이 필요로 하는 메모리를 제공한다. 만약 메모리가 너무 치명적으로 터프해 지면 시스템은 어플을 그냥 닫아 버리게 된다. 하지만 이러한 옵션은 최후의 수단에만 사용이 된다(메모리가 딸려서 전화를 못받는 상황이 된다던지 하는..).

iOS에서의 오브젝트 할당에 대해 더 알고 싶다면 Cocoa Funamental Guide 를 참조 하자.

Initializing the MoveMe Application!!


모든 C 기반의 프로그램들이 그렇듯이 모든 아이폰 어플들은 main이라고 불리는 펑션으로부터 시작된다. 좋은 소식중 한가지는 Xcode의 템플릿으로 새로운 프로젝트를 시작하게 된다면 개발자가 직접 작성하지 않아도 이부분이 자동 작성되어져 있다(감사감사 ㅠ).

다음은 MoveMe의 main 함수를 보여준다. main 함수는 프로젝트의 main.m 파일에 위치하고 있다. 모든 어플들은 main펑션을 가지고 있으며 거의 이것과 동일한 모습을 하고 잇다.  이 함수는 두가지 중요한 일을 수행한다. 첫째. 앞서 설명한 메모리 매니지먼트 레퍼런스 카운팅 시스템을 사용함으로서 어플리케이션의 탑레벨 오토 릴리즈를 생성한다. 즉 레퍼런스 카운트를 1로 만들어 주어 필요한 메모리를 할당 받는다. 둘째. MoveMe 어플의 중요한 오브젝트를 생성하기 위해 UIApplicationMain펑션을 불러온다. 그리고 이벤트 프로세싱을 반복한다. 어플리케이션은 이 함수를 프로그램을 종료할때까지 리턴시키지 않는다.

어플리케이션 델리게이트 정의!!

개발되는 프로젝드의 가장 중요한 설계적 디테일중 하나는 프로젝트 안에서 개발자가 제공하는 클래스로부터 예시되어지는 어플리케이션 델리게이트 오브젝트를 정의 하는 것이다. MoveMe 프로젝트안의 어플리케이션 델리게이트 클래스는 MoveMeAppDelegate.h 안에서 그것의 인터페이스를 선언하고 MoveMeAppDelegate.m 파일 안에서 그것의 구현을 설명한다.
한번 이 파일들을 프로젝트에 첨가하면 개발자는 인터페이스 빌더를 사용하여 어플리케이션 델리게이트로서 클래스의 인스턴스를 디자인할 수 있다. 인터페이스 빌더는 개발자가 어플리케이션의 윈도우 안의 View를 창조하고 정비하며, View의 체계를 설립하며 각 View들의 옵션을 설정하고 각 뷰들의 관계를 지정할 수 있게 사용할 수 있는 시각적 Tool이다 .이것은 시각적 Tool이기 때문에 개발자는 이러한 모든 구성품들을 드래그함으로서 사용 할 수 있다. 그럼으로 단번에 인터페이스의 변화를 알아 볼수 있기 쉽게 한다. 인터페이스 빌더는 어플의 유저 인터페이스 (UI)를 nib 파일로 저장한다.

인터페이스 빌더를 실행하고 어플리케이션 델리게이트 오브젝트의 역할이 어떻게 정의 되었는지 보기 위해 Xcode 프로젝트 윈도우의 Groups & Files 블록에 있는 MainWindow.xib파일을 더블 클릭한다. MainWindow.xib는 어플리케이션의 윈도우를 포함하며 어플리케이션 델리게이트를 포함한 우리의 어플리케이션안의 몇몇 중요한 오브젝트들간의 관계를 지정하는 nib 파일이다. 어플리케이션 델리게이트의 관계가 어떻게 구성되어 졌는지 보기 위해서 File's Owner 아이콘을 클릭하고 inspector window 를 활성화 하며 Inspector window의 Application Coonections 탭을 클릭해야 한다. 다음은 Inpector 의 모습이며 File's Owner 오브젝트가 MoveMeAppDelegate 오브젝트로 연결된 델리게이트 아웃렛을 가지고 있는 것을 보여준다.


어플리케이션 델리게이트오브젝트는 어플리케이션 안에서의 조건변경에 응답하기 위해 기본 UIApplication 오브젝트와 협력하여 작동합니다. 어플리케이션 오브젝트는 거의 모든 막중한 일을 하지만 델리게이트는 다음과 같은 몇몇 주요 행동을 합니다.

  • 어플리케이션의 윈도우와 초기 UI 셋업
  • 커스텀 데이타 엔진을 위한 추가 시동 작업 작동
  • 어플리케이션의 커스텀 URL 양식과 관련된 컨텐츠 열기
  • 디바이스의 Orientation (?) 안에서의 변화에 응답 (이게 뭔말인가요?)
  • 메모리 저용량 경고 처리
  • 어플리케이션 종료를 위한 요청 시스템 처리
초기 구동시 델리게이트 오브젝트를 위한 거의 모든 주요 사항은 다음 장 "Creating the Application Window"에 묘사되어진 어플리케이션 윈도우를 셋업 하고 유저들에게 보여주는 것 입니다. 델리게이트는 또한 어떤 요구된 오브젝트를 창조하거나 (?) 이전의 상테로(Previous state)로 어플리케이션을 되살려 불러오기와 같은 즉시 사용 (Immediate use)을 위한 어플리케이션을 준비하기 위해 필요한 어떤 작업들을 수행하여야만 합니다. (어떤 요구된 오브젝트는 뭔말인지 모르겠지만 아무튼 어플을 키면 바로 이전에 사용하던 상태로 되살리거나 등등 키면 바로 켜져야 하는 작업등을 준비해야 한다는 말인듯 하네요.). 어플리케이션이 종료 될때 델리게이트는 어플리케이션을 순차적으로 셧다운 하는 작업을 할 필요가 있고 다음 실행 사이클에 필요한 상태 정보를 저장해야 합니다.
(예를 들어 오락을 하는데 끝판왕 앞에서 전화가 와서 어플이 꺼졌다면 통화후 다시 실행했을때 다시 일탄 부터 깨야 하는 걸 막는 다는 뜻. )

아이폰 어플의 라이프 사이클과 기본 설계구조에 대한 정보를 더 많이 얻기 위해선 "Core Application Architecture" iOS Application Programming Guide.를 참조 하세요.

Creating the Application Window!!


모든 어플리케이션은 컨텐츠로 윈도우를 채우고 전체 화면을 다양히 채우는 윈도우를 창조해야할 책임이 있습니다. iOS에서의 그래픽적인 어플리케이션 구동은 다른 어플과 side-by-side로 구동되지 않습니다.(화면 분배, Picture in Picture같은걸 지원하지 않는 다는 뜻). 말인즉, 개발되는 어플리케이션은 절대로 하나이상의 UIWindow class의 인스턴스를 필요로 하지 않습니다.

윈도우들은 유저인터페이스에 필요한 드로잉 표면을 제공합니다. 하지만 view 오브젝트는 실제적인 컨텐츠를 제공합니다. view 오브젝트는 컨텐츠를 그리고 그 컨텐츠들과 상호작용하여 응답하는 UIView 클래스의 인스턴스입니다. iOS는 표, 버튼, 텍스트 필드 그리고 다른 타입의 인터렉티브 컨트롤들을 표현하기위해 스탠다드 view를 선언합니다. 개발자는 어플의 윈도우에 이런 view를 어떻게든 추가 할 수 있거나 UIView 서브클래스에 의해 정의된 커스텀 view를 선언하고 커스텀 드로윙과 이밴트 핸들링 코드를 구현할 수 있습니다. MoveMe 어플은 어플리케이션의 인터페이스를 보여주고 유저의 상호작용을 처리 하기 위해 두 종류의 view를 선언합니다; MoveMeView에 의해 구현되는 것과 PlacardView 클래스에 의해 구현되는 것.

어플리케이션 윈도우를 창조하고 시작 컨텐츠들을 가능한 빠르게 실현 시키는 것이 초기 실행의 목표 입니다.  윈도우는 MainWindow.xib nib파일로 부터 unarchived 입니다. 어플리케이션이 실행되고 이밴트 프로세스를 시작할 준비가 된 상태가 되면 UIApplication 오브젝트는 델리게이트를 applicationDidFinishLaunching 메세지로 보냅니다. 이 메세지는 컨텐츠를 어플의 윈도우에 넣고 어플이 요구하는 초기 실행 요소를 구현하기 위한 델리게이트의 큐 입니다.

MoveMe 어플에서, 델리게이트의 applicationDidFinishLaunching: 메소드는 다음과 같습니다.

1. 윈도우의 컨텐츠 뷰를 매니지 하는 일을 하는 view controller object를 창조 합니다.
2. 백그라운드 view와 전체 윈도우 프레임을 채우기 위해 moveMeView.xib nib 파일에 저장되어 있는 MoveMeView 클래스의 인스턴스로 view controller를 실행 시킵니다.
3. 윈도우의 서브 view로서 controller의 view를 추가 합니다.
4. 윈도우를 보여 줍니다.

다음의 코딩은 applicationDidFinishLaunching: 메소드이며 이것은 어플리케이션 델리게이트의 구현 파일인 MoveMeAppDelegate.m 을 선언합니다. 이 매소드는 윈도우를 위해 메인 컨텐츠 뷰를 창조하고 윈도우를 visible상태로 만들어 줍니다. 윈도우를 보여주는 것은 시스템이 어플리케이션이 이밴트 처리를 시작할 준비가 되었다는 것을 알려 줍니다.

**Note: 어플의 유저 인터 페이스를 셋업하는 것 이외에도 applicationDidFinishLaunching: 메소드를 사용 할 수 있습니다. 많은 어플리케이션들이 이것을 요구된 데이터 구조를 시작하고 유저 프리퍼런스를 읽거나 어플리케이션을 마지막 종료시의 상태로 리턴하기 위해 사용 합니다.

비록 이전의 코드가 윈도우의 백그라운드 view를 창조하고 윈도우를 보여준더라도 개발자가 이전의 코드에서 볼수 없는 것은 Welcome button을 나타내는 PlacardView클래스의 생성 이다. 이러한 행동은 MoveMeView오브젝트가 nib 파일로 부터 unarchived되었을때 initWithCoder: 매소드로 부터 불러지는 MoveMeView 클래스의 setUpPlacardView에 의해 처리 된다.
setUpPlacardView메소드는 다음의 코딩에서 보여 진다. 이 view는 PlacardView 오브젝트의 창조를 포함한다. MoveMeView 클래스는 전체 어플리케이션의 백그라운드를 제공하기 때문에 두개의 view의 관계는 Welcome 버튼을 어플리케이션 백그라운드의 탑에 보여줄 뿐 만 아니라 버튼에 연결되어진 이밴트를 MoveMeView클래스가 핸들링 할 수 있도록 허용 해 준다.

윈도우와 view생성에 관한 더 자세한 정보를 위해서는 "What Are Windows and Views?"를 참조하세요.

Drawing the Welcome Button!!

 
많은 타입의 간단한 컨텐츠를 그리기 위해서 별다른 변경 없이 UIKit에 의해 제공되는 기본 View를 사용 할 수 있습니다. (UIKit에 의해 제공되는 기본 컨텐츠들..버튼, 텍스트 레이블, 그래픽 뷰 등등..). 예를 들어 이미지 파일을 불러와 보여주기 위해서는 UIImageView 클래스를 사용할 수 있으며 Text 스트링을 보여 주기 위해서 UILabel 클래스를 사용 할 수 있습니다. MoveMeView클래스 또한 UIView 오브젝트로부터의 기본적인 프라퍼티를 사용 합니다(예를 들어 view를 솔리드 컬러로 채우기 위해 backgroundColor프라퍼티를 사용 했습니다. 이 프라퍼티는 view 오브젝트의 시작 매소드(initialization method) 안에서 코드로 설정 될 수 있습니다.  이러한 경우에 프라퍼티는 MoveMeView가 생성될때 MoveMeView.xib nib 파일안에 인터페이스 빌더의 인스펙터 윈도우의 Attributes tab에 컬러 well을 사용 하여 설정 됩니다. 하지만 개발자가 컨텐츠를 다이나믹 하게 그릴 경우, 개발자는 반듯이 UIKit안에 있는 더욱 진보된 드로윙 feature를 찾아 사용 해야 하거나 Quartz나 OpenGL ES등을 사용 해야 합니다. (UIKit에 있는 스텐다드 프라퍼티는 너무 단순해서 좀 더 고급스러운 이미지 구현을 위해선 다른 도구들을 사용 하는 것이 좋다는 말 입니다.)

MoveMe어플안에 있는 PlacardView 클래스는 Welcome 버튼을 그리고 스크린 위에서의 버튼의 위치를 관리 합니다. 비록 PlacardView클래스는 그것의 컨텐츠를 embedded UIImageView와 UILabel오브젝트를 사용해 그려 내지만, 그것은 전체적인 과정을 묘사하기 위해 컨텐츠를 명확하게 그려 냅니다.(구리지 않게 나름 괜찮다는 얘기인듯? ;;). 그 결과 이 클래스는 모든 커스톰 드로잉이 위치한 drawRect: 메소드를 view가 자리잡기 위해 구현합니다.

View의 drawRect: 메소드가 불러와 지는 동안 드로윙 환경은 실행을 준비 하기 위해 준비 되어 집니다. 개발자가 해야 할 일은 어떠한 커스텀 컨텐츠를 그리기 위한 드로윙 커맨드를 구체화 하는 일 입니다. PlacardView 클래스에서는, 컨텐츠는 리소스파일인 Placard.png로 저장되어 있는 백그라운드 이미지와 다이나믹 하게 변화될 수 있는 택스트 커스텀 스트링으로 구성 되어져 있습니다. 이 컨텐츠를 그리기 위해 클래스는 다음과 같은 과정을 밟습니다.

  1. view의 현재 경로에 백그라운드 이미지를 그립니다. (view는 이미 이미지에 맞도록 설정이 되어있기 때문에 이 과정은 전체 버튼 백그라운드를 제공합니다 .)
  2. welcome 스트링의 포지션을 계산하여 그것이 버튼의 중앙에 위치하도록 합니다. (스트링 사이즈는 변화 될 수 있기 때문에 포지션은 매번 현재 스트링 사이즈에 기반으로 하여 계산 되어 집니다.)
  3. 드로윙의 색깔을 검정으로 지정합니다.
  4. 스트링을 블랙으로 지정하고 약간 감쇄 (offset) 해 줍니다.
  5. 드로윙 컬러를 흰색으로 설정 해 줍니다.
  6. 스트링이 위치해야 할 장소에 흰색으로 다시 그려 냅니다.
다음은 PlacardView클래스를 위해 drawRect: 매소드를 보여 줍니다. PlacardImage 맴버 변수는 버튼을 위해 백그라운드 UIImage오브젝트를 가지고 있으며 currentDisplayString 맴버 변수는 Welcom 스트링을가지고 있는  NSString 오브젝트를 가지게 됩니다. 이미지를 그려낸 다음에 이 매소드는 view안의 스트링의 위치를 계산해 냅니다. 스트링의 사이즈는 스트링이 textSize맴버 변수에 저장되고 불러와질때 계산 되어져 이미 알고 있습니다. 스트링은 검은색, 흰색으로 NSString의 drawAtPoint:forWidthLwithFont:fontSize:lineBreakMode:BaselineAdjustment: 매소드를 이용해 두번 그려지게 됩니다.

좀 더 복잡한 이미지나 스트링을 표현해야 할 필요가 있다면 Quartz나 OpenGL ES를 사용 할 수 있습니다. Quartz는 벡터 기반의 Path와 이미지 그라디엔트, PDF그리도 다른 복잡한 컨텐츠를 그려내기 위해 UIKit과 함께 사용 됩니다. Quartz와 UIKit 은 같은 드로윙 환경을 기반으로 하기 때문에 view의 drawRect: 매소드로 부터 직접적으로 Quartz 함수를 불러올수 있으며 심지어 UIkit 클래스를 사용해 Quartz로 불러와 믹스 매치 하여 사용 할 수도 있습니다.

OpenGL ES는 2D와 3D 컨탵츠를 렌더할수 있게 해주는 Quartz와 UIKit의 대체 물이며 Mac OS X를 위한 OpenGL에서 찾을수 있는 함수들을 사용 할 수 있습니다. Quartz나 UIKit과 달리 drawRect:매소드를 드로윙에 사용 할 수 없습니다.  view를 사용 할 수는 있지만 vuew 오브젝트를 OpneGL ES 코드의 표면에 드로윙을 제공하기 위해 주로 사용하게 됩니다. 표면 드로잉(Drawing Surface)를 얼마나 자주 업데이트 하고 어떤 오브젝트를 사용할지는 개발자의 결정에 달렸습니다.

더 자세한 정보를 얻기 위해선 iOS Application Programming Guide의 "Supporting High-Resolution Screen"을 참조 하세요.

Handling Touch Events
!!

iOS의 멀티 터치 인터페이스는 디바이스의 멀티플 핑거 터치에 의해 실행되는 이벤트를 인지하고 응답하며 구분 할 수 있게 해 줍니다. 멀티플 핑거에 대한 응답 능력은 가공할 만한 파워를 제공하면서 전통적인 마우스 베이스의 이벤트 핸들링 시스템 오퍼레이션의 전통적인 방식과 눈에 띄게 다르게 작동 합니다. 디바이스 표면의 각 손가락의 터치에 따라 터치센서가 새로운 터치 이벤트를 제공 합니다. 각 손가락이 움직임에 따라 손가락의 새로운 포지션을 인식하기 위해 추가적인 터치 이벤트가 제공되어 집니다. 디바이스 표면에서 손가락을 떼면 시스템을 그 사실을 인지하고 이벤트를 생성합니다.

시스템은 Swipe과 같은 일반적인 제스쳐를 인지 할수 있도록 제공해 주지만 개발자는 더 많은 복잡한 제스쳐를 인지 할 수 있도록 할 책임이 있습니다. 이벤트 시스템이 새로운 터치 이벤트를 가동 할때 그것은 각 손가락의 현재 위치에 대한 정보를 포함 합니다. 각 이벤트 오브젝트는 모든 터치 활동에 관한 정보를 수반 하고 있기 때문에 개발자는 시시각각 도착하는 각 이벤트의 정보로 부터 각 손가락의 활동들을 모니터 할 수 있습니다. 개발자는 어플리케이션에 적용할 컨텐츠에 적용할 제스쳐를 찾아내기 위해  이벤트에서 이벤트로 부터 각 손가락의 움직임을 추적할 수 잇습니다.


시스템은 이벤트를 UIResponder 클래스의 인스턴스인 어플리케이션의 응답 오브젝트로 보냅니다. 아이폰 어플에서 어플리케이션의 view는 개발자의 커스텀 리스폰터 오브젝트의 벌크로 형태를 가집니다. MoveMe 어플은 두개의 view클래스를 구현 합니다. 하지만 MoveMeView클래스만이 실질적으로 이벤트 메세지에 응답 합니다. 이 클래스는 다음과 같은 UIResponder 매소드에 오버라이딩 함으로서 Welcome 버튼의 안쪽, 바깥쪽 모두의 터치를 감지 합니다.


이것의 자체 이벤트 핸들링 행동을 단순화 하기 위해 MoveMe 어플리케이션은 오직 화면에 닿은 첫번째 손가락만을 추적합니다. 이것은 이런 일을 Multi-touch 이벤트를 초기화(Default) 하는 UIView 클래스의 도움으로 가능하게 합니다. 여러개의 손가락을 추적할 필요가 없는 어플리케이션은 이러한 기능이 매우 편리하게 이용 됩니다. 시퀀스 안의 추가적인 터치에 관련된 이벤트는 절대로 view로 전달 되지 않습니다. 만약 이러한 추가적인 정보를 얻기를 원한다면 (멀티 터치에 의한 다른 손가락의 위치와 행동에 관한 정보) UIView 클레스에 있는 setMultipleTouchEnabled: 매소드를 사용 함으로서 multi touch 서포트를 다시 활성화 할 수 있습니다.

이러한 이벤트 핸들링 활동의 일부로서 MoveMeView 클래스는 다음과 같은 과정을 수행 합니다.

  1. 첫번째 터치가 감지 되었을때 어디서 이벤트가 발생하였는지를 체크한다.
  • Welcome 버튼의 바깥쪽의 더블텝은 버튼위의 String을 업데이트 한다.
  • 버튼의 중앙 안쪽의 싱글텝은 버튼 확장의 에니매이션을 실행한다.
  • 다른 모든 터치들은 무시 된다. 
     2.   만약  버튼의 안쪽에 있던 손가락이 움직이게 된다면 버튼의 포지션은 새로운 손가락의 위치에 맞추어져 업데이트 된다.
     3.   만약 손가락이 버튼의 안쪽에 위치해 있었고 그것이 화면에서 떨어지게 된다면 애니메이션이 버튼을 원래의 위치로되돌린다.
 
다음은 MoveMeView클래스를 위한 touchesBegan:withEvent: 매소드 이다. 시스템은 첫번째 손가락이 기계에 닿았을때 이 매소드를 불러 온다. 이 메소드는 모든 터치의 set을 받으며 그것으로 오직 하나의 터치 오브젝트만 내보내게 된다. (모든 정보를 다 받지만 한 손가락에 대한 정보만 사용 한다는 뜻). UITouch 오브젝트에 이쓴ㄴ 정보는 터치가 발생한 view의 신원을 확인하기 위해 사용 된다(MoveMeView오브젝트인지 PlacardView 오브젝트 인지) 그리고 터치의 탭 횟수에 관련이 되있다. (더블텝인지 싱글 텝인지). 만약 터치가 버튼의 바깥쪽에서 더블텝으로 판명이 난다면 touchesBegan:withEvent메소드는 버튼의 Welcome String을 바꾸기 위해 setupNextDisplayString 메소드를 불러온다. 만약 이벤트가 Welcome 버튼의 안쪽에서 일어난다면 그것은 버튼을 키우고 손가락의 위치를 추적하기 위해 animateFirstTouchAtPoint: 메소드를 사용 한다. 다른 모든 터치들은 무시 된다.

아래의 그림은 MoveMeView 클래스의 touchesMoved:withEvent: 메소드를 보여 준다. 시스템은 손가락이 디바이스에 닿은 다음 이 메소드를 불러 온다. 그리고 원래의 자리로 부터 손가락의 위치가 움직이면 반응한다. 무브미 어플리케이션은 Welcome 버튼에 일어난 움직임에 대해서만 추적을 한다. 그 결과 이 매소드는 이벤트의 위치를 확인하며 PlacardView오브젝ㅌ의 센터 포인트를 조정하기 위해 사용 된다. view의 움직임은 그것이 자동적으로 새로운 위치를 찾기 위한 원인이 된다.

마침내 유저의 손가락이 스크린에서 떨어지게 되면 MoveMe 어플리케이션은 버튼을 어플리케이션 윈도우의 중앙인 시작 점으로 보내기 위한 에니매이션을 실행 한다.  다음은 애니메이션을 실행 시키는 ToucheEnded:withEvent: 매소드이다.


이밴트 핸들링 프로세스를 단순화 하기 위해 touchesEnded:withEvent: 메소드는 버튼이 원래의 위치로 돌아가는 동안 view의 터치 이벤트를 일시적으로 비 활성화 시킨다. (에니매이션이 작동하는 동안의 터치는 무시된다. ) 만약 이렇게 되지 않는다면 각각의 이벤트 핸들링 메소드는 버튼이 애니메이션 작동중인지 아닌지를 알아내야할 필요가 있을 것이다. 만약 그렇다면 애니메이션을 취소한다. (만약 비활성이 안된다면 터치를 인지하고 에니매이션을 중간에 끊어 버린다.) 짧은 시간동안 유저의 상호작용을 비활성화 하는 것은 버튼을 스크린의 중앙으로 보내며 이밴트 핸들링 코드를 단순화 하고 추가 논리리의 필요성을 제거 한다. 그것의 원래 자리로 돌아 옴으로서 MoveMeView클래스의 animationDidStop:finished매소드는 유저의 상호작용을 다시 활성화 시킴으로서 모든 이벤트 사이클은 다시 처음부터 작동할 수 있게 된다.

만약 어플리케이션이 전화가 온다든가 해서 중간에 방해를 받게 된다면 view는 touchesCancelled:withEvent: 메세지로 보내진다. 이런 상황에서 어플리케이션은 디바이스의 리소스를 최소화 하기 위해 노력한다.  다음의 예제에서 placard view의 중앙과 변환은 그들의 단순히 원래 값으로 저장이 된다.

iOS에서의 핸들링 이벤트에 관한 더 많은 정보를 얻기 위해서는 iOS Application Programming Guide의 "Document Revision History"를 참조 하세요.

Animating the Button's Movement!!


아이폰 어플에서 에니메이션의 실행은 매우 중요한 역할을 한다. 에니메이션은 유저에게 정확한 정보와 즉각적인 피드백을 제공한다. 예를 들어 유저가 하나의 스크린을 다른 스크린으로 대체 하는 대신 생산성 어플리케이션 안에서의 계층적 데이타를 탐험 할때에 아이폰 어플리케이션은 각 새로운 스크린을 위치 시키기 위해 에니메이션을 사용한다. 에니메이션 움직임의 방향은 유저가 올리는지 내리는지를 보여주고 보고있는 새로운 정보가 있음을 비쥬얼 큐로 제공한다.

이것의 중요성 때문에 애니메이션의 지원은 UIKit의 클래스에 이미 탑재가 되어 있다. MoveMe어플리 케이션은 Welcome 버튼의 다른 양상의 애니메이션을 구현함으로서 이러한 지원의 이점을 얻는다. (UIKit의 애니메이션 지원을 사용 했다는 얘기..;;). 유저가 처음으로 버튼을 터치 했을때 어플리케이션은 버튼의 사이즈를 빠르게 확대 시키는 애니메이션을 적용한다. 유저가 버튼을 놓았을때 또다른 애니메이션이 그것을 원래의 자리로 돌리기위해 작동한다. 이러한 애니메이션의 작성의 기본 스텝은 기본적으로 같다.

  1. View의 beginAnimations: context: 메소드를 불러 온다.
  2. 에니매이션 프라퍼티를 설정한다.
  3. View의 에니매이션을 시작하기 위해 commitAnimations매소드를 불러 온다.
아래의 그림은 버튼을 첫 터치시 펄스를 사용하기 위한 애니메이션 코드를 보여 준다. 이 메소드는 애니메이션의 길이를 지정하고 그것의 새로운 사이즈를 비율적으로 적용한 버튼의 변화를 적용 시킵니다. 이 애니메이션이 완료 되었을때 애니메이션은 버튼을 약간 줄어들게하고 터치 아래의 placard veiw를 움직이는 펄스 애니메이션을 완료하는 애니메이션 델리게이트의 growAnimationDidStop:finished:context: 매소드를 불러옵니다.
빌트인 view기반 에니매이션의 사용에 대한 더 많은 정보를 얻기 위해 iOS Application Programming Guide의 "Animation Views"를 참조 하세요. 코어 애니메이션에 관한 더많은 정보를 iOS Application Programming Guide의 "Applying Core Animation Effects"를 참조 하세요.

Finishing the Application!!


부터는 다음 포스트에 올릴께요!




Objective-C 배우기: 초급 SDK Anatomy

Object-C는 복잡한 객체지향 프로그래밍을 가능하게 해주는 간단하게 디자인된 컴퓨터 랭귀지 입니다. Object-C는 클래스와 매소드 또한 클래스의 다이나믹한 확장을 도와주는 다른 구성들을 선언하기 위한 Syntax를 제공하는  ANSI C 언어의 확장입니다.

**주의 : 이 글에서는 어떠한 C 언어에 관련된 정보를 제공하지 않습니다. 만약 C언어와 친숙하지 않다면 진행하기 전에 C의 기본적인 부분을 숙지하는 것이 좋습니다.

또한 객체지향성 프로그래밍에 관련된 최소한의 기본 컨셉정도는 알고 있는 것이 좋습니다. 오브젝트의 활용과 객체지향 디자인 패턴들의 사용은 코코아 어플리케이션 디자인의 기본이며 어떻게 그들이 서로 작용하는 가는 이해하는 것은 어플을 개발하는데 치명적인 부분입니다. 기본적 컨셉을 훑어 보기 위해 "Object-Oriented Programming with Objective-C"를 참조하세요. 또한 "Cocoa Fundamentals Guide"를 참조 하는 것도 코코아의 디자인 패턴에 대한 정보를 얻는데 도움이 될 것 입니다. **

만약 C언어에 익숙하고 객체지향 언어를 통한 프로그래밍을 해본 경험이 있다면 다음의 정보들은 Objective-C의 기본 신텍스를 이해하는데 도움이 될 것입니다. 캡슐화(encapsulation), 계승(inheritance), 다형성(inheritance)과 같은 많은 전통적인 객체지향적 컨샙들이 모두 Objective-C에 존재 합니다. 하지만 몇몇 중요한 다른점이 있지만 이 글에서 설명 되어질 것이며 더 많은 디테일에 대한 참조 문헌을 참고하길 바랍니다. The Objective-C Programming Language 참조

Objective-C: C의 상위 집합!!

Objective-C는 C 언어의 ANSI버전의 상위 집합이며 같은 기본 신텍스를 제공합니다. C코드와 같이 헤더파일, 소스파일들을 작성된 코드의 자세한 구현으로부터 각각 공개 선언하기 위해 정의 합니다.(은)는 발 번역이고 아무튼 헤더파일, 소스파일들을 정의하고 선언하고 불러오는 과정이 C언어의 그것과 같다는 말인듯..어쨋든 Objective-C의 헤더파일들은 다음과 같은 확장자를 사용합니다.

간단히 요약하면 .h는 헤더파일로서 Class, Type, 함수와 상수선언을 포함합니다.
.m은 소스파일로서 Objective-C와 C코드 둘다 포함할수 있는 소스파일 확장자 입니다.
.mm또한 소스파일로서 C++의 코드또한 포함할 수 있습니다. C++에 포함된 클래스와 틍징들을 사용할때 사용됩니다.

소스코드에 헤더파일을 포함하기 원하면 #import 를 직접 사용하는 것이 일반 적입니다. 이것은  #include 와 같지만 이것은 같은 파일이 결코 한번이상 포함되지 않을 것이라는것을 확인하는 것이 다릅니다. Objective-C 샘플들과 문서들은 모두 #import를 지향하며 개발자들 또한 그렇게 해야 할 것입니다. (아마 메모리나 용량을 줄이기 위해서 인듯 하네요.정확히 아시는 분계시면 답글좀..)

Classes!!

다른 많은 객체지향 언어들과 같이 Objective-C의 클래스들도 몇몇 데이타와 데이터를 운용하는 액션을 캡슐화 해주는 기본구조를 제공한다. 오브젝트는 클래스의 런타임 인스턴스이며 클래스의 매소드에 포인터와 클래스에 의하여 변수가 선언되는 인스턴스의 인-메모리 카피를 포함한다. (은)는 발번역이고..클래스는 설계도, 오브젝트는 실제물이라고 생각하면 맞을듯 하다.

Objective-C 안의 특정 클래스들은 두가지 분명한 것을 요구하며 그것은 바로 Interface 와 Implementation(구현)이다. 인터페이스 몫은 클래스 선언을 갖게 되며 인스턴스의 변수와 매소드를 클래스에 관련하여 정의 한다. 인터페이스는 보통 .h 파일로 저장이 된다.  Implementation  몫은 클래스의 매소드를 위한 실질적 코드를 갖게 된다. Implementation은 주로 .m 파일로 저장된다.

다음 그림은 코코아의 기본 클래스인 NSObject 로부터 계승된 MyClass라는 클래스를 선언하는 신택스를 보여줍니다. 이 클래스 선언은 @interface 컴파일러 명령을 시작으로 @end 명령으로 끝이 납니다. 뒤이어 클래스의 이름이 오고 (콜론 :) 으로 분리되어 Parent Class 가 뒤따라 옵니다. 클래스의 인스턴스 변수들은 대괄호 블럭안에서 선언이 됩니다. {}. 그리고 뒤이어 클래스에의해 선언되는 매소드의 리스트들이 따라옵니다. 세미콜론이 각 인스턴스 변수와 메소드 선언뒤에 따라오게 됩니다.

**주의: 이 인터페이스는 오직 메소드만 선언하였습니다. : 클래스는 또한 프라퍼티들도 선언할 수 있습니다. 프라퍼티에 대해 더 자세히 알아보기 위해서는 Declared Properties 를 확인하세요 **

Objective-C는 오브젝트를 포함한 변수를 위하여 Strong typing, weak typing 두가지 모두를 지원합니다. Strong typed 변수는 변수 타입 선언안에 클래스의 이름을 포함합니다. Weakly typed 변수는 오브젝트를 위하여 id 를 사용 합니다. Weakly typed 변수는 주로 알려지지 않은 모음 안의 오브젝트의 특정한 타입이 있는 클래스 모음 등을 위하여 종종 쓰여 집니다. 스트롱타입드 변수를 주로 쓰셨던 분들은 위크리 타입드 변수가 문제가 될 것이라 생각하실지 모르겠지만 사실 그들은 Objective-C 안에서 굉장히 유연하며 엄청나게 다이나믹하게 사용됩니다.(쉽게 이야기 하면 스트롱타입은 사용될 클래스 이름이 가지고 있음으로서 선언된 클래스 안에서만 쓰이지만 위클리타입드는 id를 할당받아 필요할때마다 불러와서 쓸 수 있다 라고 해석 되어 집니다.)

다음의 예시는 Strongly와 Weakly typed 변수의 선언에 관한 예입니다.

MyClass *myObject1; // strong typing
id            myObject2; // Weak typing


첫번째 선언에 *를 주의 하세요. Objective-C에서 오브젝트 레퍼런스들은 포인터입니다. 이것이 완전히 이해가 가지 않더라도 걱정하시 마세요. Objective-C를 시작하기 위해 포인터에 대해 전문가가 될 필요는 없습니다. 단지 *이 앞에 붙은 변수 이름은 Strongly-typed 오브젝트 선언이라고 기억만 하세요. id 타입은 포인터를 의미합니다.


Methods and Messaging!!

 Objective-C안에서의 클래스는 Instance Methods와 Class Methods,두가지 타입의 매소드를 선언할 수 있습니다. 인스턴스 매소드는 클래스의 특정한 인스턴스영역에서 실행되는 매소드 입니다. 다르게 이야기 하자면, 개발자가 인스턴스 매소드를 불러오기 전에 반듯이 클래스의 인스턴스를 만들어 놔야 합니다. 반면, 클래스 매소드는, 인스턴스를 미리 만들어 놓을 필요는 없습니다. 나중에 만들면 됩니다.

매소드의 선언은 매소드타입의 정체성과 리턴타입, 하나 이상의 시그네쳐 키워드 그리고 파라메터 타입과 이름 정보로 이루어 져 있습니다.  다음은 insertObject:atIndex: 인스턴스 매소드의 선언에 관한 예제 입니다.


이 선언은 이 매소드가 인스턴스 매소드라는 것을 보여주는 - 표시와 함깨 시작합니다. 매소드의 실제 이름은 "insertObject:atIndex:" 이며 이것은 콜론 문자를 포함한 모든 시그네쳐 키워드의 연속 입니다. 콜론 케릭터는 파라메터가 존재함을 표시 합니다. 만약 매소드가 파라메터를 가지고 있지 않다면 첫번째 시그네쳐 키워드의 뒤에 콜론을 찍게 됩니다. 이 매소드의 예제는 두개의 파라매터를 가지게 됩니다.

매소드를 불러오고 싶다면 오브젝트를 Messaging 합니다. 메세지는 메소드가 필요로 하는 파라메터 인포메이션에 덧붙여 따라 오는 메소드 시그네쳐 입니다. 오브젝트로 보내지는 모든 메세지는 즉시 보내 짐으로 Objective-C 클레스들의 다형적 행동을 가능하게 합니다.

메세지는 [] 에 의해 닫히게 됩니다. 오브젝트가 받는 메세지는 왼쪽에 있고 (메세지에 의해 필요로 하게 되는 어떤 파라메터에 덧 붙여 따라오게 되는 )메세지는 오른쪽에 위치하게 됩니다. 예를 들어 insertObject:atIndex:를 myArray변수에 있는 오브젝트로 보내기 위해서 다음과 같은 신텍스를 사용하게 됩니다.

[myArray insertObject:anObject atIndex:0];

임시 결과를 저장하기 위해 수많은 로컬 변수 선언을 피하기 위해 Objective-C는 메세지들을 nest하게 해줍니다. (셋트로 만들어 줍니다.) 각 nested 메세지들로 부터의 return value는 또 다른 메세지의 파라메터나 타겟으로서 사용되어 집니다. 예를 들어, values를 검색하기 위해 메세지와 이전의 예제에서 사용된 변수를 대체 할 수 있습니다. 그럼으로 오브젝트를 어레이에 삽입하거나 어레이 오브젝트를 사용하기 위한 메소드를 가진 myAppObject 라는 오브젝트를 가지고 있다면 다음과 같은 것을 보기위해 위에 언급한 예제를 사용할 수 있습니다.

[[myAppObject the Array] insertObject:[myAppObject objectToInsert] atIndex:0];

Objective-C는 또한 오브젝트의 프로퍼티 벨류를 갖거나 지정하는 인스턴스 메소드인 엑세서 매소드(Accessor method)를 위해 . 신텍스를 제공합니다. Accessor Method는 오브젝트의 상테를 갖거나 지정하고 주로 -(type)propertyName 과 -(void)setPropertyName:(type) 의 형태를 취하게 됩니다. dot syntax를 사용하기 위해 이전의 예제를 다음과 같이 수정해야 합니다.

[myAppObject.theArray insertObject:[myAppObject objectToInsert] atIndex:0];

또한 Assignment를 위해 dot syntax를 사용할수도 있습니다.

myAppObject.theArray = aNewArray;

이것은 단순히 [myAppObject setTheArray:aNewArray]; 를 쓰기위한 다른 종류의 신텍스 일뿐입니다.

비록 이전의 예제가 메세지를 클래스의 인스턴스로 보내지만, 또한 메세지를 클래스로 직접 보낼 수도 있습니다. 클레스에 메세지를 보낼때 특정한 메소드는 반듯이 인스턴스 메소드대신 클래스 메소드로 정의되어져야 합니다.

우리는 주로 클래스의 새로운 인스턴스를 창조하거나 클래스와 관련된 어떤 공유된 정보를 어세스 하기위해 클래스 매소드를 팩토리 매소드로서 사용 합니다. 클래스 매소드 선언을 위한 신택스는 한가지 예외를 제외하고 인스턴스매소드와 동일합니다. 하지만 - 사인 대신 + 사인을 사용하게 됩니다.

다음 예제는 우리가 클래스를 위해 어떻게 클래스 매소드를 팩토리 매소드로서 사용하는 지를 보여 줍니다. 이러한 경우, 어레이 매소드는 NSArray 클래스상의 클래스 메소드이며 클래스의 새로운 인스턴스를 할당하고 개시하며 작성한 코드로 리턴시켜주는  NSMutableArray에 의해 계승되어 집니다.

다음은 앞서 설명한 예제로 부터 MyClass의 구현을 보여 줍니다. 클래스 선언과 같이 클래스 구현은 두개의 컴파일러 실행(@implementation과 @end)에 의해 식별되어 집니다.이 실행들은 컴파일러가 해당하는 클래스를 이용해 닫혀진 매소드와 작용하기 위해 정보를 제공합니다. 매소드의 선언은 인터페이스 내에서 코드블록포함을 제외한 그것에 해당하는 선언을 맞춰 줍니다.

Declared Properties!!

선언된 프라퍼티는 선언을 번복하고 때에따라 엑세서 매소드를 구현하는데 쓰여지는 편리한 표기 입니다.

우리는 클래스 인터페이스안에 매소드 선언으로 프라퍼티 선언을 포함합니다. 기본적인 방법은 type information과 프라퍼티의 이름을 수반하는 @property 컴파일러 명령을 사용하는 것입니다. 또한 우리는 어떻게 엑세서 매소드의 행동을 정의할 것인지에 대한 개별 옵션으로 프라퍼티를 형성할 수도 있습니다.

@property BOOL flag;

@property (copy) NSString *nameObject;  //  copy the object during assignment.

@property (readonly) UIView *rootView;  // Declare only a getter method.

각 읽기쉬운 프라퍼티(Readable property라고 썻는데 무슨 의도일까요?;;)는 '그' property와 같은 이름으로 매소드를 명시하였습니다. 각 쓸수 있는 프라퍼티 (Writable Property...아..읽을수 있는 쓸수 있는...이였군요)는 프라퍼티이름의 첫 글자가 대문자로 쓰여진 곳에 setPropertyNamel, 의 형태로 추가적인 매소드를 명시하였습니다.

작성된 클래스 구현에 우리는 또한 컴파일러가 특정화된 선언에 따라 메소드를 실행 하도록 요구하는 @synthesize 컴파일러 명령을 사용할 수 있습니다.

@synthesize flag;

@synthesize nameObject;

@synthesize rootView;

또한 @synthesize 를 한줄로 합칠수도 있죠 :)

@synthesize flag, nameobject, rootView;

솔직히 말하자면 프라퍼티는 당신이 써야하는 불필요한 코드들의 양을 줄여 줍니다. 대부분의 엑세서 매소드는 비슷한 방법으로 구현되기 때문에 프라퍼티들은 클래스안에 노출되는 각 프라퍼티를 위한 게터/세터(Getter/Setter)메소드의 구현을 필요에 의해 제거합니다. 그대신, 우리는 우리가 원하는 프라퍼티 선언의 사용의 행동을 명시하여야 하고 그런다음 컴파일 타임에 선언에 기초하여 실제 게터/세터 매소드를 합성해야 합니다.

클래스에 어떻게 프라퍼티를 선언하는지에 대한 정보는 Declared Properties를 참조하세요.



Strings!!

C의 상위 집합으로서 Objective-C는 Strings에 대한 명시로서 C와 같은 규약을 가지고 있습니다. 다시말해, 단일 문자는 따옴표로 묶이게 되며 여러글자들은 썅따옴표로 묶이게 됩니다.  그러나 Objective-C 프레임워크는 보통 C스타일의 스트링을 사용하지 않습니다. 그대신 NSString 오브젝트로 String들을 떠넘기게 됩니다.

NSString 클래스는 임의 길이의 스트링을 저장하기위한 빌트인 매모리 관리, 유니코드 지원, printf스타일 포멧팅 유틸리티등등 우리가 기대하는 모든 장점을 가진 string을 위한 object wrapper를 제공합니다. 어떤 스트링들은 보통 터프하게 사용되기 때문에 Objective-C는 지속되는 values로부터 NSString 오브젝트를 창조하기 위해 간단한 명시를 제공합니다. 이러한 간단함을 이용하기 위해 해야할 것은 다음과 같이 이전의 따옴표, 쌍따옴표 스트링을 @심볼과 함께 쓰는 것 입니다. 아래는 그에 대한 예시문 입니다 .



Protocols!!

프로토콜은 어떠한 클래스로부터 구현될수 있는 매소드를 선언 합니다. 프로토콜은 그들자체는 클래스가 아닙니다. 그들은 단순히 다른 오브젝트들이 구현을 위해 응답하는 인터페이스를 선언하기만 합니다. 당신이 당신의 클래스들중 하나에 있는 프로토콜의 매소드를 구현할때 당신의 클래스는 프로토콜을 확정하라고 이야기 할 것입니다.

프로토콜은 주로 델리게이트 오브젝드를 위한 인터페이스를 명시하기위해 사용되어 집니다. 프로토콜과 델리겡트 그리고 다른 오브젝트들간의 상호작용을 들여다 보기위한 가장 좋은 방법은 예제를 통한 방법입니다.

UIApplication 클래스는 어플리케이션의 요구된 행동을 구현합니다. 어플리케이션의 현재 상황에 관한 안내를 단순히 받기위해 UIApplication 서브클래스에 집중하기 보다는 UIapplication 클래스는 이러한 알림들을 그것 자체에 할당된 델리게이트 오브젝트의 특정 매소드를 불러옴으로서 전달해 줍니다. UIApplicationDelegate프로토칼의 매소드를 구현하는 오브젝트는 그러한 알림들을 받을수 있으며 적절한 응답을 제공합니다. 당신은 당시의 클래스 컨펌을 상속되는 클레스의 이름뒤에 <>안의 프로토콜 이름의 인터페이스 블록에 넣음으로서 프로토콜에 컨펌시킵니다.(문장이 참...). 당신은 당신이 구현하는 프로토콜 매소드를 선언할 필요가 없습니다.

예제
프로토콜의 선언은 프로토콜은 Parent 클래스를 가지고 있지 않은 것과 인스턴스 변수를 선언하지 않는다는 것을 빼고는 클래스인터페이스 선언과 비슷해 보입니다. 다음의 예제는 하나의 매소드로 단순한 프로토콜을 선언하는 것을 보여 줍니다.

많은 델리게이트 프로토콜의 경우 프로토콜을 적용하는 것은 단순히 프로토콜에의해 정의된 매소드를 구현하는 일입니다. 몇몇 프로토콜들은 당신에게 당신이 지원하는 프로토콜을 명쾌히 지정할 것을 요구하고 프로토콜들을 요구된 것과 옵션적인 매소드 모두를 명시할 수 있습니다. 그러나 점점 개발을 할수록 당신은 프로토콜의 사용에대해 더 배우기위해 시간을 사용해야 하며 Protocols를 읽음으로 인해 어떻게 사용하는지를 더 이해할수 있습니다.

For More Information!!

위의 정보들은 옵젝트 씨의 기본적인것에 대해 친숙해 지는 것을 주 목적으로 쓰여졌습니다. 위의 것들만으로도 머리가 깨질 것 같지만 더 어려운것들이 기다리고 있으니 기대해라 이것들아 어흥 무섭지!!! 라고 써있군요..


다음엔 용어정리와 함께 좀 더 쉽게 이해해 보도록 해보아요 ㅠ

1 2