CLOSE SEARCH

Cocoa Fundamentals Guide – What Is Cocoa?

Cocoa는 OS X와 iOS 모두를 위한 어플리케이션 환경으로 객체지향 소프트웨어 라이브러리, 런타임 시스템, 통합 개발환경으로 구성되어 있다. What is Cocoa? 에서는 이러한 정의를 확장하여 두 플랫폼 존재하는 코코아의 목적과 능력, 구성요소에 대해 설명한다. 이처럼 코코아에 대한 기술적인 설명서를 읽는 것은 코코아를 이해하려는 개발자에게 중요한 첫번째 단계이다.

The Cocoa Environment

코코아는 OS X와 iOS에서 실행되는 어플리케이션들을 위한 실행 환경을 제공하는 객체지향 프레임워크의 모음이다. 코코아는 OS X에서 가장 큰 우위를 가지는 어플리케이션 환경이고, iOS를 위한 유일한 어플리케이션 환경이다. Mail과 Safari와 같이 OS X와 iOS에서 볼 수 있는 대부분의 어플리케이션들이 코코아 어플리케이션이다. Xcode라고 하는 통합 개발환경은 두 플랫폼의 어플리케이션 개발을 지원한다. 이런 개발 환경과 코코아의 조합은 고품질의 어플리케이션을 쉽게 개발할 수 있도록 해준다.

 

Introducing Cocoa

코코아는 모든 어플리케이션 환경과 마찬가지로 런타임에 관련된 것과 개발에 관련된 것을 제공한다. 런타임 측면에서 보면 코코아 어플리케이션은 사용자 인터페이스를 제공하고 OS의 다른 시각적 요소들과 긴밀하게 통합되어 있다.

하지만 프로그래머에게 더욱 흥미로운 것은 개발에 관련된 것이다. 코코아는 강력한 성능을 가지는 고품질의 OS X, iOS 어플리케이션을 신속하게 개발할 수 있도록 해주는 객체 지향 소프트웨어 컴포넌트(클래스)들의 모음이다. 이 클래스들은 재사용이 가능하고 유연한 소프트웨어 개발 도구이다. 클래스를 그대로 사용하거나 특정 요구사항에 맞게 확장할 수도 있다. 사용자 인터페이스부터 데이터 포멧팅까지 필요한 거의 모든 코코아 클래스들이 존재한다. 이미 존재하는 클래스를 서브클래싱해서 예상하지 못한 요구사항들을 충족시킬 수도 있다.

코코아는 모든 객체지향 개발환경 중에서 가장 뛰어난 혈통 중에 하나로, NeXTSTEP으로 소개된 1989년부터 지금까지 계속해서 개선되고 테스트 되어왔다. 코코아의 훌륭하고 강력한 설계는 어플리케이션 뿐만 아니라 명령줄 도구, 플러그인과 다양한 형식의 번들 등 모든 종류의 소프트웨어를 신속하게 개발하는 데에 매우 적합하다. 코코아는 어플리케이션에서 필요로 하는 대부분의 동작과 외관을 공짜로 제공해 주므로 어플리케이션의 고유한 기능을 개발하는데 더 많은 시간을 할애할 수 있다.

[note color=”#fffbb8″]iOS Note: iOS의 코코아는 어플리케이션 개발을 제외한 다른 형식의 실행파일 개발은 지원하지 않는다.[/note]

코코아 소프트웨어를 개발할 때 여러 프로그래밍 언어를 사용할 수 있지만 필수적으로 요구되는 언어는 Objective-C이다. Objective-C는 객체지향 프로그래밍을 지원하는 기능을 통해 확장된 ANSI C의 superset이다. 이 언어에 포함된 몇가지 규약들은 쉽게 배우고 사용할 수 있다. Objective-C는 ANSI C에 기초를 두고 있기 때문에 C 코드와 Objective-C 코드를 자유롭게 혼합하여 사용할 수 있다. 또한, /usr/include에 있는 BSD 라이브러리와 같은 비-코코아 인터페이스에 정의되어 있는 함수들을 호출할 수도 있다. C++ 코드를 코코아 코드와 함께 사용하여 컴파일된 코드를 동일한 실행파일에 링크할 수도 있다.

[note color=”#fffbb8″]OS X Note: OS X에서는 PyObjC, RubyCocoa와 같은 스크립팅 브릿지를 코코아에서 사용할 수 있다. 각 브릿지 언어들은 파이썬과 루비 언어로 코코아 어플리케이션을 작성할 수 있도록 해준다. 이들은 파이썬이나 루비 객체들이 Objective-C 객체에 메시지를 보내거나 Objective-C 객체가 파이썬 또는 루비 객체에 메시지를 보낼 수 있도록 해주는 객체지향 프로그래밍 언어이고, 인터프리팅 언어, 대화식 언어이다. 자세한 정보는 Ruby and Python Programming Topics에서 제공한다.[/note]

가장 중요한 코코아 클래스 라이브러리들은 각 플랫폼에서 두개의 코어 프레임워크로 포장되어 있다. OS X에서는 Foundation 프레임워크와 AppKit 프레임워크이고, iOS에서는 Foundation 프레임워크와 UIKit 프레임워크이다. 모든 프레임워크들이 그렇듯이 이 프레임워크들은 동적 공유 라이브러리와 헤더파일, API 문서, 그리고 프레임워크와 관련된 리소스들을 포함하고 있다. Foundation과 AppKit 또는 UIKit의 결합은 그래픽적인 사용자 인터페이스와 연관되어 있는 클래스와 그렇지 않은 클래스 사이의 구분을 반영하고 있다. 각 플랫폼에서 두개의 코어 프레임워크들은 어플리케이션을 최종 결과물로 만들어내는 모든 코코아 프로젝트에서 필수적으로 사용된다. 두 플랫폼은 코어 프레임워크만큼 유용하고 중요한 코어 데이터 프레임워크도 추가적으로 지원한다.

OS X에는 WebKit 프레임워크, Address Book 프레임워크와 같은 다양한 프레임워크들도 포함하고 있다. 앞으로도 더 많은 코코아 프레임워크들이 OS에 추가될 것이다. 자세한 정보는 “The Cocoa Frameworks”에서 제공한다.

 

How Cocoa Fits into OS X

OS X는 구조적으로 봤을 때 Darwin에서부터 다양한 어플리케이션 프레임워크와 이들이 지원하는 사용자 경험으로 구성된 일련의 소프트웨어 계층이다. 중간에 존재하는 레이어들은 Core Service와 Application Service라는 두개의 주요한 프레임워크에 포함되어 있는 시스템 소프트웨어를 나타낸다. 일반적으로 하나의 계층에 있는 구성요소는 아래에 있는 계층과 종속 관계를 가진다. 그림 1-1은 이러한 구조적인 배경에서 코코아의 위치를 보여준다.

Figure 1-1  Cocoa in the architecture of OS X

Figure 1-1 Cocoa in the architecture of OS X

예를 들어, 아쿠아 사용자 인터페이스와 Quartz를 랜더링 하는데 중요한 역할을 담당하는 시스템 구성요소들은 Application Services 계층의 한 부분을 차지한다. 그리고 스택의 가장 아래쪽에는 Darwin이 위치한다. 코코아를 포함한 OS X의 모든 것들은 Darwin에 전적으로 의존한다.

코코아는 OS X용 어플리케이션 개발에 필수적인 두개의 Objective-C 프레임워크를 가진다.

[list style=”star”]

  • AppKit. 어플리케이션 프레임워크 중 하나인 AppKit은 어플리케이션의 사용자 인터페이스에 출력하는 객체들을 제공하고 이벤트 처리와 그리기를 포함한 어플리케이션 동작에 사용되는 구조를 정의한다. AppKit에 대한 설명은 “AppKit (OS X)”에서 제공한다.
  • Foundation. Core Services 레이어에 있는 이 프레임워크는 객체의 기본 동작을 정의하고 이를 관리하기 위한 매커니즘을 구성하며, 기본 데이터 형식, 컬렉션, OS 서비스를 위한 객체들을 제공한다. Foundation은 본질적으로 Core Foundation 프레임워크의 객체지향 버전이다. Foundation에 대한 설명은 “Foundation”에서 제공한다.

[/list]

AppKit은 Core Services 계층에 위치하고 있는 Foundation에 대한 직접적이고 밀접한 의존성을 가진다. 코코아 클래스와 특정 프레임워크들을 조금 더 상세히 살펴본다면 코코아가 OS X의 다른 부분들과 의존성을 가지고 있는 부분이나 자신의 인터페이스를 통해 기초적인 기술을 공개하고 있는 부분이 보이기 시작할 것이다. 코코아가 의존하고 있거나 자신의 클래스와 메소드들을 통해 공개하고 있는 몇가지 주요한 기초 프레임워크는 Core Foundation, Carbon Core, Core Graphics(Quartz), Launch Services와 같은 것들이다.

[list style=”star”]

  • Core Foundation. Foundation 프레임워크에 있는 다수의 클래스들은 이에 상응하는 Core Foundation opaque type을 기반으로 한다. 이와 같은 밀접한 관계는 “toll-free bridging”(호환되는 Core Foundation과 Foundation 형식 사이의 형변환)을 가능하게 해준다. Core Foundation의 일부 구현은 Darwin 계층의 BSD를 기반으로 한다.
  • Carbon Core. AppKit과 Foundation은 자신이 제공하는 일부 시스템 서비스에 Carbon Core 프레임워크를 활용한다. 예를 들어, Carbon Core는 코코아가 다양한 파일 시스템 형식 사이의 변환을 위해 사용하는 File Manager를 가지고 있다.
  • Core Graphics. 코코아의 그리기와 이미지 처리 클래스들은 Quartz와 윈도우 서버를 구현하는 Core Graphics 프레임워크를 기반으로 한다.
  • Launch Services. NSWorkspace 클래스는 Launch Services의 기초가 되는 기능들을 노출한다. 또한, 코코아는 어플리케이션과 문서와 연관된 아이콘을 얻기 위해서 Launch Services의 어플리케이션 등록 기능을 사용한다.

[/list]

애플은 코코아의 프로그래밍 인터페이스들이 어플리케이션에서 일반적으로 필요로하는 기본적인 기능에 대한 접근을 제공할 수 있도록 신중하게 설계하였다. 하지만 코코아의 인터페이스를 통해 공개되지 않은 기능이 필요하거나 어플리케이션에서 발생하는 것들에 대한 좀 더 세부적인 제어가 필요하다면 기초적인 프레임워크들을 직접 사용할 수도 있다. (Core Graphics가 한가지 예이다. 여기에서 제공하는 함수나 OpenGL 함수를 통해 코코아 그리기 메소드에서 제공하는 것보다 좀 더 복잡한 이미지를 그릴 수 있다.) 다행히, 이러한 하위 수준의 프레임워크에 있는 대부분의 인터페이스들이 표준 ANSI C를 통해 작성된 프레임워크에 의존적이기 때문에 이들을 사용하는 것은 문제가 되지 않는다.

[note color=”#fffbb8″]Further Reading: Mac Technology Overview는 OS X의 프레임워크, 서비스, 기술과 다른 구성요소들에 대한 개요를 제공한다. OS X Human Interface Guidelines는 Aqua 사용자 인터페이스가 보여지고 동작하는 방식에 대해 구체적으로 설명한다.[/note]

 

How Cocoa Fits into iOS

iOS의 어플리케이션 프레임워크 계층은 Cocoa Touch라고 부른다. 코코아 터치가 의존하는 iOS의 인프라는 OS X의 코코아와 유사하지만 몇가지 중요한 차이점이 존재한다. iOS의 구조를 나타내는 그림 1-2를 그림 1-1과 비교해보자.  iOS 다이어그램은 OS X 다이어그램과 마찬가지로 코어 서비스 프레임워크와 그래픽, 미디어 프레임워크, 라이브러리들로 구성된 중간 계층을 가진다. 마찬가지로 하나의 계층에 있는 구성요소들은 종종 아래쪽 계층에 대한 의존성을 가진다.

Figure 1-2  Cocoa in the architecture of iOS

Figure 1-2 Cocoa in the architecture of iOS

일반적으로 UIKit을 지원하는 iOS 시스템 라이브러리와 프레임워크들은 OS X에 있는 라이브러리와 프레임워크들의 하위집합이다. 예를 들어, iOS에는 Carbon 어플리케이션 환경, 명령줄 접근, 인쇄 프레임워크와 서비스들이 존재하지 않으며, QuickTime도 플랫폼에서 제외되어 있다. 하지만 iOS에 의해 지원되는 디바이스의 특성으로 인해 iOS에 특화된 몇가지 공개 프레임워크와 비공개 프레임워크도 존재한다.

다음의 내용은 파운데이션 계층을 시작으로 iOS 스택의 각 계층에서 발견할 수 있는 몇가지 프레임워크에 대해 설명한다.

[list style=”star”]

  • Core OS. 이 계층에는 커널, 파일 시스템, 네트워크, 보안, 전원 관리, 그리고 다양한 디바이스 드라이버들이 포함되어 있다. 또한 POSIX/BSD 4.4/C99 API 사용을 지원하고 다양한 서비스에 대한 시스템 수준의 API를 제공하는 libSystem 라이브러리도 가지고 있다.
  • Core Services. 이 계층에 있는 프레임워크들은 문자열 조작, 컬렉션 관리, 네트워킹, URL 도구, 주소록 관리, 환경설정 등과 같은 주요한 서비스들을 제공한다. 또한 GPS, 나침반, 가속도계, 자이로스코프와 같이 디바이스의 하드웨어 특성에 기반하는 서비스들도 제공한다. 이 계층에 있는 프레임워크에는 Core Location, Core Motion, System Configuration 등이 있다. 이 계층은 문자열, 컬렉션과 같은 일반적인 데이터 형식에 대한 추상화를 제공하는 프레임워크인 Foundation과 Core Foundation을 모두 포함하고 있다. Core Frameworks 계층은 객체 그래프 관리와 영속화를 위한 프레임워크인 Core Data도 포함하고 있다.
  • Media. 이 계층에 있는 프레임워크와 서비스들은 Core Services 계층을 기반으로 하며 Cocoa Touch 계층에 그래픽 서비스와 멀티미디어 서비스들을 제공한다. 여기에는 Core Graphics, Core Text, OpenGL ES, Core Animation, AVFoundation, Core Audio, 비디오 재생이 포함된다.
  • Cocoa Touch. 이 계층에 있는 프레임워크들은 iOS 기반의 어플리케이션을 직접 지원한다. Game Kit, Map Kit, iAd와 같은 프레임워크들이 여기에 속한다.

[/list]

Cocoa Touch 계층과 Core Services 계층은 각각 iOS 어플리케이션 개발에서 특히 중요한 Objective-C 프레임워크를 가진다. 이들은 iOS에서 중심이 되는 코코아 프레임워크이다.

[list style=”star”]

  • UIKit. 이 프레임워크는 어플리케이션이 사용자 인터페이스에 표시하는 객체들을 제공하며 이벤트 처리, 그리기와 같이 어플리케이션의 동작에 필요한 구조를 정의한다. UIKit에 대한 설명은 “UIKit (iOS)”에서 제공한다.
  • Foundation. 이 프레임워크는 객체의 기본 동작을 정의하고, 이를 관리하기 위한 매커니즘을 구성하며, 기본 데이터 형식, 컬렉션, OS 서비스를 위한 객체들을 제공한다. Foundation은 본질적으로 Core Foundation 프레임워크의 객체지향 버전이다.

[/list]

[note color=”#fffbb8″]Note: 이 문서는 플랫폼 사이에서 공통적인 것들을 언급할 때는 “Cocoa”라는 용어로 통칭한다. 특정 플랫폼에 국한된 내용을 언급할 필요가 있을 때는 “Cocoa in OS X”와 같은 문구를 사용한다.[/note]

OS X의 코코아와 마찬가지로 iOS의 코코아 프로그래밍 인터페이스들은 어플리케이션이 기초적인 기능에 접근할 수 있도록 해준다. 보통 원하는 기능을 구현하기 위해 저수준의 프레임워크를 활용하는 UIKit 또는 Foundation 메소드나 함수는 이미 존재한다. 하지만 API를 통해 공개되지 않은 기능이 필요하거나, 좀 더 세밀한 제어가 필요한 경우에는 기초적인 프레임워크들을 직접 사용할 수도 있다. 예를 들어, UIKit은 텍스트를 출력하기 위해 WebKit을 사용하며 텍스트 출력과 관련된 몇가지 메소드들을 제공한다. 하지만 텍스트 레이아웃과 폰트 관리를 제공하는 Core Text를 사용할 수도 있다. 이러한 하위 수준의 프레임워크에 존재하는 대부분의 인터페이스들이 표준 ANSI C를 통해 작성된 프레임워크에 의존적이기 때문에 이들을 사용하는 것은 문제가 되지 않는다.

[note color=”#fffbb8″]Further Reading: iOS의 프레임워크, 서비스와 기타 다른 요소에 대한 자세한 정보는 iOS Technology Overview에서 제공한다.[/note]

 

Features of a Cocoa Application

OS X에서는 단 한줄의 코드를 작성하지 않고 코코아 어플리케이션을 만들 수 있다. Xcode에서 새로운 Cocoa Application 프로젝트를 만든다음 프로젝트를 빌드하면 된다. 이것이 전부다. 물론 이러한 어플리케이션은 흥미롭지 않을 것이다. 하지만 아주 간단한 이 어플리케이션은 더블클릭을 통해 실행되고, Dock에 자신의 아이콘을 표시하며, 사용자의 명령에 따라 자신의 메뉴와 창을 표시하거나 감춘다. 그리고 실행중인 다른 어플리케이션들과 함께 잘 동작하며 명령에 따라 종료되기도 한다. 창을 옮기거나 크기를 변경할 수 있고, 최소화하거나 닫을 수도 있다. 창에서 표시하고 있는 공백을 출력할 수도 있다.

iOS에서도 동일한 작업을 할 수 있다. Xcode에서 프로젝트 템플릿 중 하나를 선택해서 프로젝트를 만든다음, 프로젝트를 빌드하고 iOS Simulator에서 실행하면 된다. 어플리케이션은 시뮬레이터나 디바이스의 Home 버튼을 클릭할(또는 누를) 때 종료된다. 어플리케이션을 실행하려면 시뮬레이터에서 어플리케이션의 아이콘을 클릭한다. 기본 어플리케이션은 추가적인 동작을 가지기도 한다. 예를 들어 Utility Application 템플릿을 사용해서 만들어진 어플리케이션은 정보 아이콘(“i”)을 클릭하거나 탭할 때 초기 뷰를 두번째 뷰로 전환한다.

약간의 코드를 통해 할 수 있는 것들을 생각해보자.

[note color=”#fffbb8″]iOS Note: iOS에서 실행중인 어플리케이션의 특성과 동작은 제약이 많은 환경으로 인해 Mac app과는 상당한 차이점을 가진다. iOS의 제약과 어플리케이션의 기능에 대한 내용은 iOS App Programming Guide에서 설명한다.[/note]

코코아는 프로그래밍에 필요한 노력의 관점에서 개발자들에게 무료로 사용할 수 있는 많은 것들과 저비용을 사용할 수 있는 많은 것들을 제공한다. 물론 생산적인 코코아 개발자가 된다는 것은 어쩌면 새로운 개념, 디자인 패턴, 프로그래밍 인터페이스, 개발 도구에 익숙해 진다는 것을 의미할 수 있으며 이러한 노력을 무시할 수는 없다. 익숙함이 더 나은 생산성을 만들어 낸다. 프로그래밍은 주로 코코아에서 제공하는 프로그램 구성요소와 프로그램의 특정 로직을 정의하는 코드를 조합한 다음, 이 모든 것들을 조화시키는 행위를 나타낸다.

다음은 코코아가 어떠한 방식으로 적은 노력을 통해 어플리케이션에 가치를 더하는지에 대하여 설명한다.

[list style=”star”]

  • Basic application framework—코코아는 이벤트 기반 동작과 어플리케이션, 창, 작업영역 관리를 위한 인프라를 제공한다. 대부분의 경우 이벤트를 직접 처리하거나 렌더링 라이브러리로 그리기 명령을 보낼 필요가 없다.
  • User-interface objects—코코아는 어플리케이션의 사용자 인터페이스를 위해 미리 준비된 풍부한 객체들을 제공한다. 이 객체의 대부분은 인터페이스 빌더의 라이브러리에서 사용할 수 있다. 라이브러리에서 인터페이스 화면으로 객체를 드래그하고, 속성을 구성하고, 다른 객체와 연결하면 된다.코코아 사용자 인터페이스 객체에는 다음과 같은 것들이 존재한다.Windows
    Text fields
    Image views
    Date pickers
    Sheets and dialogs
    Segmented controls
    Table views
    Progress indicators
    Buttons
    Sliders
    Radio buttons (OS X)
    Color wells (OS X)
    Drawers (OS X)
    Page controls (iOS)
    Navigation bars (iOS)
    Switch controls (iOS)OS X의 코코아는 접근성(accessibility)을 향상시키고, 유효성 검사를 수행하고, 사용자 인터페이스와 커스텀 객체에 있는 객체들을 쉽게 연결할 수 있는 기술들을 특징으로 가진다.
  • Drawing and imaging—코코아는 locking graphical focus기능과 뷰 또는 뷰의 일부분을 “dirty” 상태로 표시할 수 있는 기능을 가진 프레임워크를 통해 커스텀 뷰를 효율적으로 그릴 수 있도록 해준다. 코코아는 베지어 곡선을 그리고, 아핀 변환, 이미지 합성, PDF 생성 등을 위한 프로그래밍 도구를 포함하고 있다.
  • System interaction—OS X에서 코코아는 어플리케이션이 파일 시스템, 작업영역, 또는 다른 어플리케이션과 상호작용 할 수 있는 방법을 제공한다. iOS의 코코아는 어플리케이션에 전달된 URL을 통해 참조된 리소스를 처리할 수 있도록 해준다. 그리고 로컬 시스템에서 파일 시스템과의 상호작용을 관리하고 로컬 통지를 예약할 수 있는 기능을 제공한다. 
  • Performance—코코아는 어플리케이션의 성능을 향상시키기 위해서 동시 실행(Concurrency), 멀티 스레딩, 리소스 지연 읽기, 메모리 관리, 런루프 조작에 대한 프로그래밍 지원을 제공한다.
  • Internationalization—코코아는 어플리케이션 국제화를 위한 풍부한 설계를 제공함으로써 텍스트, 이미지, 사용자 인터페이스와 같이 지역화된 리소스들을 지원할 수 있도록 해준다. 코코아의 접근법은 사용자의 선호 언어 목록을 기반으로 하며, 지역화된 리소스들은 어플리케이션 번들 내부에 위치한다. 코코아는 자신이 발견한 설정에 따라 자동으로 사용자의 설정과 가장 일치하는 지역화된 리소스를 선택한다. 또한 지역화된 문자열을 생성하고 사용할 수 있는 도구와 인터페이스들을 제공한다. 게다가 코코아의 텍스트 조작은 기본적으로 유니코드 기반이기 때문에 국제화에 있어서 이점을 가진다.
  • Text—OS X에서 코코아는 텍스트 뷰를 표시하는 간단한 것부터 자간(kerning)과 합자(ligature), 철자 검사, 정규식, 이미지 삽입과 같이 복잡한 것까지 텍스트로 할 수 있는 대부분의 작업을 가능하게 해주는 세련된 텍스트 시스템을 제공한다. iOS의 코코아에는 네이티브 텍스트 시스템이 없고 텍스트와 관련된 기능이 제한적이지만, 철자 검사, 정규식, 텍스트 입력 시스템과의 상호작용에 대한 지원은 포함하고 있다. 
  • Preferences—user defaults 시스템은 시스템전역 데이터베이스를 기반으로 한다. OS X와 iOS에서 어플리케이션 설정을 저장하는 절차는 서로 다르다.
  • Networking—코코아는 표준 인터넷 프로토콜을 통해 서버와 통신하고, 소켓을 통해 통신하고, 봉주르를 활용할 수 있는 프로그래밍 인터페이스를 제공한다. OS X의 코코아는 하나의 코코아 프로세스가 동일한 컴퓨터나 다른 컴퓨터에 있는 다른 프로세스와 통신할 수 있도록 해주는 분산 객체 아키텍처를 포함하고 있다. iOS의 코코아는 통지를 전달받도록 등록된 디바이스에 푸시 통지를 전달할 수 있는 기능을 지원한다. 
  • Printing—두 플랫폼에 있는 코코아는 모두 인쇄를 지원한다. 이들의 인쇄 아키텍처는 이미지, 문서, 어플리케이션의 컨텐츠를 다양한 제어를 통해 인쇄할 수 있도록 해준다. 가장 단순한 단계에서는 적은 코드를 통해 뷰의 컨텐츠를 출력하거나 이미지 또는 PDF 문서를 출력할 수 있다. 좀 더 복잡한 단계에서는 출력할 컨텐츠의 포멧을 정의하고, 출력 작업이 수행되는 방식을 제어하거나 페이지를 구분할 수 있다. OS X에서는 Print 대화상자에 악세사리 뷰를 추가할 수 있다.
  • Undo management—사용자의 행동들은 undo manager에 등록할 수 있고, undo manager는 사용자가 적절한 메뉴 항목을 선택할 때 작업 되돌리기(undo)와 재실행(redo)을 처리한다. 이 manager는 개별 스택에서 undo 작업과 redo 작업들을 유지한다.
  • Multimedia—두 플랫폼 모두 비디오와 오디오를 프로그래밍적으로 지원한다. OS X의 코코아는 QuickTime 비디오 지원을 제공한다.
  • Data exchange—코코아는 copy-paste 모델을 사용해서 어플리케이션 내부와 어플리케이션 사이의 데이터 교환을 간소화한다. OS X에서 코코아는 drag-and-drop 모델을 지원하며 Services 메뉴를 통해 어플리케이션 공유 기능을 지원한다.

[/list]

OS X의 코코아는 몇가지 다른 기능들도 가진다.

[list style=”star”]

  • Document-based applications—코코아는 워드 프로세서와 같이 자신만의 창을 가지는 다수의 문서로 구성되어 있는 어플리케이션을 위한 아키텍처를 정의한다. Xcode에서 “Document-based application” 프로젝트 형식을 선택한다면, 이러한 종류의 어플리케이션에서 사용되는 다수의 구성요소들이 자동으로 생성된다.
  • Scripting— application scriptability information과 코코아 클래스들의 지원을 통해 어플리케이션에서 스크립트를 사용할 수 있다. 즉, 어플리케이션은 AppleScript 스크립트를 통해 전달된 명령에 반응할 수 있다. 또한 스트립트를 실행하거나 개별 Apple 이벤트를 사용해서 다른 어플리케이션으로 명령을 전달하거나 다른 어플리케이션으로부터 데이터를 받을 수 있다. 결과적으로 스트립트를 사용할 수 있는 모든 어플리케이션은 사용자와 다른 어플리케이션에 서비스를 제공할 수 있다.

[/list]

 

The Development Environment

코코아 소프트웨어는 주로 Xcode와 Interface Builder의 두가지 개발 어플리케이션을 사용해서 개발한다. 이러한 어플리케이션을 전혀 사용하지 않고 코코아 어플리케이션을 개발하는 것도 가능하다. 예를 들어, Emacs와 같은 텍스트 편집기를 사용해서 코드를 작성하고 makefiles를 사용해서 명령줄에서 어플리케이션을 빌드할 수 있다. 그리고 gdb 디버거를 사용해서 명령줄에서 어플리케이션을 디버그할 수도 있다. 하지만 왜 이렇게 어려운 길을 택하는 것인가?

[note color=”#fffbb8″]Note: “Xcode”는 때때로 개발도구와 프레임워크의 모음을 나타내는데 사용되고, 때로는 프로젝트를 관리하고, 소스 코드를 편집하고, 실행코드를 빌드 할 수 있도록 해주는 어플리케이션을 특정하는데 사용된다.[/note]

Xcode와 Interface Builder의 기원은 코코아의 기원과 맥을 같이하며, 그 결과 도구와 프레임워크 사이에 높은 수준의 호환성을 가지고 있다. Xcode와 Interface Builder는 코코아 소프트웨어 프로젝트를 설계, 관리, 빌드, 디버그하는 작업을 아주 쉽게 만들어준다.

개발 도구와 문서를 설치할 때 설치 위치를 선택할 수 있다. 전통적으로 이 위치는 /Developer 였지만, 파일 시스템 내의 어떤 위치도 가능하다. 이 문서는 이 위치를 지정하기 위해서 <Xcode>를 사용한다. 따라서 개발 어플리케이션들은 <Xcode>/Applications 디렉토리에 설치된다.

 

Platform SDKs

Xcode 버전 3.1과 iOS가 도입된 때부터 소프트웨어 프로젝트를 만들때는 반드시 플랫폼 SDK를 선택해야 한다. SDK는 OS X 또는 iOS를 대상으로 하는 실행파일을 빌드할 수 있도록 해준다.

플랫폼 SDK는 특정 플랫폼과 OS를 대상으로 하는 소프트웨어를 개발하는데 필요한 모든것을 담고 있다. OS X SDK는 프레임워크, 라이브러리, 헤더 파일, 시스템 도구로 구성되어 있다. iOS의 SDK는 동일한 구성요소들을 가지고 있으며 플랫폼에 특화된 컴파일러와 다른 도구들을 추가로 포함하고 있다. iOS 시뮬레이터에서 사용되는 별도의 SDK도 존재한다.(“The iOS Simulator Application” 참고) 모든 SDK는 플랫폼에 특화된 빌드 설정과 프로젝트 템플릿을 포함하고 있다.

 

Overview of Development Workflows

사용되는 도구 뿐만 아니라 개발 흐름에서도 OS X와 iOS의 어플리케이션 개발은 차이를 가진다.

OS X의 일반적인 개발 흐름은 다음과 같다.

  1. Xcode에서 OS X SDK의 템플릿을 사용해서 프로젝트를 생성한다.
  2. 코드를 작성한 다음 Interface Builder를 사용해서 어플리케이션의 사용자 인터페이스를 구성한다.
  3. 프로젝트의 타겟과 실행 환경을 정의한다.
  4. Xcode의 디버깅 기능을 사용해서 어플리케이션을 테스트하고 디버깅한다. 디버깅의 일환으로 Console 창에서 시스템 로그를 확인할 수 있다.
  5. 사용가능한 하나 이상의 성능 도구를 사용해서 어플리케이션의 성능을 측정한다.

iOS 개발의 경우 어플리케이션 개발 흐름이 조금 복잡하다. 개발을 시작하기 전에 반드시 플랫폼 개발자로 등록해야 한다. 그런 다음 어플리케이션을 빌드하기 위해서 다음과 같은 과정을 따라야 한다.

  1. 원격 디바이스를 구성한다. 이 구성을 통해 필요한 도구와 프레임워크와 다른 구성요소들이 디바이스에 설치된다.
  2. Xcode에서 iOS SDK의 템플릿을 사용해서 프로젝트를 생성한다.
  3. 코드를 작성하고 어플리케이션의 사용자 인터페이스를 구성한다.
  4. 프로젝트의 타겟과 실행 환경을 정의한다.
  5. 어플리케이션을 빌드한다.
  6. iOS 시뮬레이터나 원격으로 연결된 실제 디바이스를 통해 어플리케이션을 테스트하고 디버깅한다.
  7. 사용가능한 하나 이상의 성능 도구를 사용해서 어플리케이션의 성능을 측정한다.

[note color=”#fffbb8″]Further reading: iOS의 개발 흐름에 대한 상세한 정보를 Tools Workflow Guide for iOS에서 제공한다.[/note]

 

Xcode

Xcode는 OS X와 iOS을 위한 Apple의 통합 개발 환경을 제공하는 핵심 어플리케이션이다. 또한 개발 초기부터 배포까지 대부분의 상세 사항들을 대신 처리해주는 어플리케이션이기도 하다. Xcode는 다음과 같은 기능을 제공한다.

[list style=”star”]

  • 프로젝트 생성과 플랫폼 선택, 타겟 요구사항 설정, 의존성 구성, 빌드 구성 등의 프로젝트 관리
  • syntax coloring, 자동 들여쓰기와 같은 기능을 가진 편집기를 통한 소스코드 작성
  • 프로젝트의 구성요소 탐색 및 검색
  • 프로젝트 빌드
  • iOS 시뮬레이터와 디바이스를 통한 프로젝트 디버깅

[/list]

Xcode는 C, C++, Objective-C, Objective-C++로 작성된 소스코드로부터 프로젝트를 빌드한다. 명령줄 도구, 프레임워크, 플러그인, 커널 익스텐션, 번들, 어플리케이션과 같이 OS X에서 지원하는 모든 형식의 실행파일을 생성한다. iOS의 경우, 어플리케이션 실행파일만 생성할 수 있다. Xcode는 빌드와 디버그 도구, 실행파일 패키징, 빌드 과정에 대해서 제한이 거의없는 사용자화를 허용한다. 또한 CVS, Subversion, Perforce와 같은 다양한 소스코드 관리 시스템을 지원하므로 저장소에 파일을 추가하고, 변경사항을 반영하고, 업데이트된 버전을 가져오고 버전을 비교하는 등 대부분의 소스관리 작업을 수행할 수 있다.

Xcode는 코코아 개발에 특히 더 접합하다. Xcode는 프로젝트를 생성할 때 프로젝트 형식에 상응하는 프로젝트 템플릿을 사용해서 초기 개발 환경을 구성한다. 그리고 코코아 소프트웨어를 컴파일할 때 다음과 같은 옵션들을 제공한다.

[list style=”star”]

  • GCC—The GNU C compiler (gcc).
  • LLVM-GCC— GCC가 LLVM(Low Level Virtual Machine) 컴파일러의 front end로 사용되는 구성. LLVM은 빠른 최적화 시간과 고품질의 코드 생성 기능을 제공한다. 이 옵션은 OS X 10.6 버전 이상을 대상으로 빌드된 프로젝트에서만 사용할 수 있다.
  • Clang—LLVM 컴파일러를 위해 특별히 고안된 front end. Clang은 빠른 컴파일 시간과 뛰어난 진단 기능을 제공한다. 이 옵션은 OS X 10.6 버전 이상을 대상으로 빌드된 프로젝트에서만 사용할 수 있다.

[/list]

컴파일러 옵션에 대한 자세한 정보는 Xcode Build System Guide에서 제공한다.

Xcode는 디버깅을 위해서 gdb와 Clang 정적 분석기(Clang Static Analyzer)를 제공한다. Clang 정적 분석기는 소스코드 분석을 위한 프레임워크와 C, Objective-C 프로그램에서 버그를 발견하는 독립형 도구(standalone tool)로 구성되어 있다. 상세한 정보는 http://clang-analyzer.llvm.org에서 얻을 수 있다.

Xcode는 Interface Builder와 같은 주요한 개발 어플리케이션과 잘 통합되어 있다.

 

Interface Builder

코코아 프로젝트에서 사용되는 두번째로 주요한 개발 어플리케이션은 Interface Builder이다. Interface Builder는 이름에서도 알 수 있듯이 사용자 인터페이스를 만드는데 사용되는 그래픽 도구이다. 이 어플리케이션은 Cocoa가 NeXTSTEP라는 이름으로 시작된 시점부터 존재해 왔다. 그러므로 Cocoa와 Interface Builder가 빈틈없이 통합된 것은 결코 놀라운 일이 아니다.

Interface Builder는 네가지 주요한 요소를 중심으로 구성되어 있다.

[list style=”star”]

  • Nib Files. nib 파일은 사용자 인터페이스에 표시되는 객체들을 아카이브 형식으로 담고 있는 file wrapper이다. 아카이브는 본질적으로 객체에 대한 정보를 담고 있는 객체 그래프이다. Interface Builder에서 사용자 인터페이스를 생성하고 저장할 때, 인터페이스를 재생성하기 위해 필요한 모든 정보는 nib 파일에 저장된다. nib 파일은 사용자 인터페이스를 손쉽게 지역화하는 방법을 제공한다. Interface Builder는 프로젝트에 있는 지역화 디렉토리 내부에 nib 파일을 저장한다. 이 nib 파일은 프로젝트가 빌드될 때 생성된 번들내의 지역화 디렉토리로 복사된다. Interface Builder는 nib 파일의 컨텐츠를 nib document 창을 통해 제공한다. nib document 창은 windows, menus, controller objects와 같은 최상위 객체와 같이 nib 파일에 존재하는 중요한 객체에 대한 접근을 제공한다. 그림 1-4는 nib 파일이 열려있는 Interface Builder를 보여준다. nib document 창과 지원 창들이 열려있다.

    Figure 1-4  The TextEdit Document Properties window in Interface Builder

    Figure 1-4 The TextEdit Document Properties window in Interface Builder

  • Object library. Interface Builder의 Library 창은 사용자 인터페이스에 추가할 수 있는 객체를 담고있다. 이러한 객체는 일반적인 UI 객체부터 컨트롤러 객체, 커스텀 뷰 객체에 이르기까지 다양하다. Library 창은 객체를 종류별로 그룹화하며 이를 통해 객체를 탐색하거나 특정 객체를 검색할 수 있게 해준다. Interface Builder는 객체가 라이브러리에서 인터페이스로 드래그 될 때 해당 객체의 기본 인스턴스를 생성한다. 속성창(inspector)을 통해 객체의 크기와 구성을 변경하고 다른 객체와 연결할 수도 있다.
  • Inspector. Interface Builder는 사용자 인터페이스 객체를 구성하는데 사용되는 창인 inspector(속성창)를 가지고 있다. 속성창은 객체의 초기 런타임 구성을 설정하는데 사용되는 다양한 속성을 가진다. 그림 1-4에 있는 속성창은 텍스트 필드의 주요 속성을 보여준다. 또한, 에니메이션 효과, 이벤트 처리, 객체 사이의 타겟-액션 연결과 같은 속성도 제공한다. OS X 프로젝트의 nib 파일에는 AppleScript, 바인딩과 관련된 추가 항목이 존재한다.
  • Connections panel. 연결 패널은 선택된 객체의 아웃렛과 액션 연결을 보여주고 이러한 연결을 관리할 수 있도록 해주는 context-sensitive display이다. 연결 패널을 표시하려면 대상 객체를 Control 키를 누른 상태로 클릭하거나 마우스 왼쪽 버튼을 클릭한다. 그림 1-5는 연결 패널을 보여준다.

    Figure 1-5  The Interface Builder connections panel

    Figure 1-5 The Interface Builder connections panel

[/list]

Interface Builder는 객체를 움직이거나 크기를 변경할 때마다 파란색 선을 사용해서 객체의 위치나 크기가 Aqua human interface guidelines에 부합하는지를 보여준다. 여기에는 해당 객체에 권고되는 크기와 정렬, 그리고 창의 경계 또는 인터페이스에 있는 다른 객체와의 상대적인 위치가 포함된다.

Interface Builder는 Xcode와 긴밀하게 통합되어 있다. 그래서 커스텀 클래스의 아웃렛, 액션, 바인딩 가능한 속성들을 인식한다. 이러한 항목들을 추가, 삭제 또는 변경할 때 변경사항을 인식하고 화면 상태를 업데이트 한다.

[note color=”#fffbb8″]Further Reading: Interface Builder에 대한 더 자세한 정보는 Interface Builder User Guide에서 제공한다. 또한 “Communicating with Objects”에서는 아웃렛, 타켓-액션 매커니즘, 코코아 바인딩 기술에 대한 개요를 제공한다.[/note]

 

The iOS Simulator Application

iOS 프로젝트의 경우 프로젝트의 플랫폼 SDK로 iOS 시뮬레이터를 선택할 수 있다. Xcode는 프로젝트를 빌드하고 실행할 때 시뮬레이터를 실행하고 사용자 인터페이스 부분을 조작할 수 있도록 해준다. 시뮬레이터를 통해 어플리케이션을 실제 디바이스에 설치하기 전에 디버깅 할 수 있다.

최종 디버깅은 항상 디바이스에서 수행하여야 한다. 시뮬레이터는 디바이스를 완벽하게 대체하지 못한다. 예를 들어, 손가락 터치 대신에 마우스 포인터를 사용해야 하며, 세개 이상의 손가락을 통한 인터페이스 조작은 불가능하다. 또한, iOS에 특화된 버전의 OpenGL 프레임워크를 사용하지 않으며 OS X 버전의 Foundation, Core Foundation, CFNetwork 프레임워크와 libSystem을 사용한다.

더욱 중요한 것은, 시뮬레이터에서 실행되는 어플리케이션의 성능이 디바이스에서 실행되는 경우와 동일하다고 가정하지 않아야 한다는 것이다. 시뮬레이터는 기본적으로 iOS 어플리케이션을 “guest” 맥 앱으로 실행한다. 그로 인해 실제 디바이스에 비해 훨씬 강력한 성능을 가지게 된다.

[note color=”#fffbb8″]Further reading: iOS 시뮬레이터에 대한 상세한 정보는 Tools Workflow Guide for iOS에서 제공한다.[/note]

 

Performance Applications and Tools

Xcode와 Interface Builder가 코코아 어플리케이션 개발에 사용되는 주요한 도구이기는 하지만, 이 외에도 자유롭게 사용할 수 있는 다양한 도구들이 존재한다. 이러한 도구의 대부분은 성능과 관련된 어플리케이션이다.

Instruments

Instruments는 Xcode 3.0에서 도입된 어플리케이션으로 다수의 성능 테스트 도구를 동시에 실행하고 분석 결과를 타임라인 형식의 그래픽으로 확인할 수 있게 해준다. 이를 통해 CPU 사용량, 디스크 읽기와 쓰기, 메모리 통계, 스레드 활동, 가비지 컬렉션, 네트워크 통계, 디렉토리와 파일 사용과 같은 측정 정보를 시간의 흐름에 따른 그래프로 확인할 수 있다. 측정된 데이터를 동시에 표시하여 데이터 사이의 관계를 파악하는데 도움을 주기도 한다. 또한 그래프 뒤에 특정 데이터를 표시하기도 한다.

[note color=”#fffbb8″]Further Reading:  Instruments 어플리케이션에 대한 모든 정보는 Instruments User Guide에서 제공한다.[/note]

 

Shark

Shark는 프로그램의 실행에 대한 시간기반 프로필(time-based profile)을 생성할 수 있도록 해주는 성능 분석 어플리케이션이다. 이 어플리케이션은 지정된 기간동안 함수 호출을 추적하고 메모리 할당을 그래프로 표시한다. Shark를 통해 단일 어플리케이션이, 드라이버, 커널 익스텐션과 같은 커널 컴포넌트가 포함된 전체 시스템의 정보를 추적할 수 있다. 또한 파일 시스템 호출을 감시하고 시스템 호출과 메모리 할당을 추적하며 코드에 대한 정적 분석을 수행하고, cache misses, page faults 등에 대한 정보를 수집한다. Shark는 C, Objective-C, C++ 등의 언어로 작성된 코드에 대한 분석을 지원한다.

 

Other Performance Applications (OS X)

다양한 어플리케이션들이 OS X 프로그램의 성능을 측정하고 분석하는데 사용된다. 이러한 어플리케이션들은 <Xcode>/Applications/Performance Tools 디렉토리에 위치한다.

[list style=”star”]

  • BigTop은 시간의 흐름에 따른 성능 추세를 그래프로 표시하고, 메모리 사용량, page faults, CPU 사용량과 같은 데이터의 실시간 출력을 제공한다.
  • Spin Control은 응답하지 않는 어플리케이션의 정보를 자동으로 추출한다. 어플리케이션을 시작하고 테스트하는 동안 Spin Control을 백그라운드에서 실행상태로 둔다. Spin Control은 어플리케이션이 응답하지 않는 상태가 되면 해당 시점에 어플리케이션이 수행하고 있던 작업에 대한 정보를 모으기 위해 어플리케이션의 정보를 자동으로 추출한다.
  • MallocDebug는 어플리케이션에서 현재 할당되어 있는 모든 메모리 블록을 할당시점의 호출 스택으로 구성하여 보여준다. 어플리케이션의 메모리 할당량, 메모리 할당 지점, 다수의 메모리를 할당한 함수 등을 한눈에 확인할 수 있다. 또한 어떤 부분에서도 참조되고 있지 않은 메모리를 찾을 수 있기 때문에 메모리 누수를 발견하고 해당 메모리가 할당된 정확한 위치를 찾는데 도움을 준다. 
  • QuartzDebug는 어플리케이션의 화면출력을 디버그하는데 도움을 주는 도구이다. 특히, 그리기와 이미지 처리를 많이 사용하는 어플리케이션에 유용하다. QuartzDebug는 다음과 같은 다양한 디버깅 옵션을 가지고 있다.
    • 그리기 작업 후에 그래픽 컨텍스트의 내용을 flush하는 Auto-flush drawing
    • 업데이트되기 직전에 해당 화면 영역을 노란색으로 채우는 방식
    • 시스템 전역 창 목록의 정적 스냅샷(각 창의 소유자와 소비하는 메모리양을 보여줌)을 얻는 옵션.

[/list]

성능 분석의 경우 다음과 같은 명령줄 도구를 사용할 수도 있다.

[list style=”star”]

  • top : 현재 실행중인 프로세스의 통계정보를 주기적으로 추출하여 보여준다.
  • gprof : 프로그램의 실행 개요(execution profile)를 생성한다.
  • fs_usage : 파일 시스템 접근 통계를 보여준다.

[/list]

이 외에도 성능 분석과 개발 작접을 위한 다양한 명령줄 도구를 사용할 수 있다. 일부는 /usr/bin 디렉토리와 /usr/sbin 디렉토리에 존재하고, 애플이 개발한 일부 명령줄 도구들은 <Xcode>/Tools 디렉토리에 설치되어 있다. 대부분의 도구는 메뉴얼 페이지를 제공하며 이를 통해 사용법을 참고할 수 있다.

[note color=”#fffbb8″]Further Reading: Performance Overview는 코코아 어플리케이션 개발에서 사용할 수 있는 성능 도구와 어플리케이션에 대한 상세한 정보와 성능과 관련된 개념, 기술, 지침, 전략 등에 관한 정보를 제공한다. Cocoa Performance Guidelines는 코코아의 성능 지침에 대한 내용을 다룬다.[/note]

 

The Cocoa Frameworks

무엇이 하나의 프로그램을 코코아 프로그램으로 만드는 것일까? 코코아 개발에 다양한 언어를 사용할 수 있기 때문에 프로그래밍 언어는 아니다. 비록 복잡하고 많은 시간이 소요되지만 명령줄에서 코코아 어플리케이션을 생성할 수 있기 때문에 개발 도구도 아니다. 코코아 프로그램의 공통점은 최상위 클래스인 NSObject로부터 상속된 객체로 구성되어 있고 Objective-C 런타임을 기반으로 하고 있다는 것이다. 이러한 사실은 모든 코코아 프레임워크에도 적용된다.

[note color=”#fffbb8″]Note: 최상위 클래스에 대한 내용은 약간 수정될 필요가 있다. 먼저, Foundation 프레임워크는 NSProxy라는 또다른 최상위 클래스를 제공한다. 하지만 NSProxy는 코코아 프로그래밍에서 거의 사용되지 않는다. 두번째, 최상위 클래스를 직접 만들수도 있지만 Objective-C 런타임과 상호작용 할 수 있도록 코드를 작성해야 하므로 많은 작업이 필요하며 아마도 시간을 투자할 만한 가치가 없을 것이다.[/note]

시스템에는 다수의 코코아 프레임워크가 존재하고, 애플과 서트파티들은 항상 더 많은 프레임워크들을 출시하고 있다. 이렇게 풍부한 코코아 프레임워크 중에서도 각 플랫폼에 있는 두개의 프레임워크는 코어 프레임워크로 대표되고 있다.

[list style=”star”]

  • In OS X: Foundation and AppKit
  • In iOS: Foundation and UIKit

[/list]

Foundation, AppKit, UIKit 프레임워크는 코코아 어플리케이션 개발에 있어서 필수이며 다른 모든 프레임워크들은 선택적이다. AppKit을 링크하지 않으면 OS X용 코코아 어플리케이션을 개발할 수 없고 UIKit을 링크하지 않으면 iOS용 코코아 어플리케이션을 개발할 수 없다. 게다가 Foundation 프레임워크를 링크하지 않으면 어떠한 종류의 코코아 소프트웨어도 개발할 수 없다. Foundation과 AppKit 프레임워크에 있는 클래스, 함수, 데이터 형식, 상수들은 “NS”접두어를 사용하고, UIKit 프레임워크에 있는 것들은 “UI” 접두어를 사용한다.

[note color=”#fffbb8″]Note: 코코아 프레임워크는 OS X 10.5 버전에서 64비트를 지원하도록 수정되었다. iOS 역시 64비트를 지원한다. 이로 인해 코코아 API가 전반적으로 수정되었으며, int와 unsigned int를 대체할 수 있는 NSInteger, NSUInteger와 대부분의 float를 대체할 수 있는 CGFloat 형식이 도입되었다. 대부분의 코코아 어플리케이션은 64비트로 바로 전환할 필요가 없지만, 전환이 필요한 어플리케이션을 위한 전환 도구와 지침들이 준비되어 있다. 64-Bit Transition Guide for Cocoa는 이와 관련된 상세 내용을 다룬다.[/note]

코코아 프레임워크는 다양한 저수준의 작업들을 대신 처리해준다. 예를 들어, 정수와 부동 소수점 값을 저장하고 조작하는 클래스들은 값의 메모리 배열 방식(endianness)을 자동적으로 처리해 준다.

이어지는 섹션은 세가지 주요한 코코아 프레임워크의 특징과 클래스에 대해 알아보고 몇가지 부가적인 프레임워크에 대해 간단히 설명한다. 각 코어 프레임워크들은 다수의 클래스를 가지고 있기 때문에 이들을 기능에 따라 분류하고 있다.

 

Foundation

Foundation 프레임워크는 어떠한 형식의 코코아 프로그램에서도 사용될 수 있는 클래스들의 기초 계층을 정의한다. Foundation에 있는 클래스와 AppKit에 있는 클래스를 구별하는 기준은 사용자 인터페이스이다. 객체가 사용자 인터페이스에 표시되지 않거나 사용자 인터페이스를 지원하기 위한 목적으로 사용되지 않는다면 이 객체의 클래스는 Foundation에 속한다. 명령줄 도구와 인터넷 서버와 같이 Foundation 클래스만을 사용해서 코코아 프로그램을 만들 수도 있다.

Foundation 프레임워크는 다음과 같은 내용을 염두에 두고 설계되었다.

[list style=”star”]

  • 객체의 기본 동작을 정의하고 메모리 관리, 객체 가변성(object mutability), 통지(notification)에 대한 일관적인 규약을 도입한다.
  • 번들 기술과 유니코드 문자열을 통해 국제화와 지역화를 지원한다.
  • 객체 영속화를 지원한다.
  • 객체 배포(distribution)를 지원한다.
  • 이식성 지원을 위한 몇가지 OS 독립 방안을 제공한다.
  • 숫자, 문자열, 컬렉션과 같은 기본형에 대한 객체 래퍼(wrapper)를 제공한다. 포트, 스레드, 파일 시스템과 같은 서비스와 시스템 요소에 접근하는데 사용되는 유틸리티 클래스도 제공한다.

[/list]

의미상 AppKit 프레임워크나 UIKit 프레임워크와 링크되는 어플리케이션인 코코아 어플리케이션은 반드시 Foundation 프레임워크와도 링크되어야 한다. 클래스 계층구조는 NSObject라는 최상위 클래스를 공유하며, 대부분은 아니지만 많은 AppKit, UIKit 메소드와 함수들이 Foundation 객체를 파라미터나 리턴값으로 가진다.

 

Foundation Paradigms and Policies

Foundation은 특정 상황에서 프로그램의 객체 사이의 일관된 동작과 예상을 유지하지 위해서 코코아 프로그램에 몇가지 패러다임과 정책들을 사용하고 있다.

[list style=”star”]

  • Object retention and object disposal. Objective-C 런타임과 Foundation 프레임워크는 객체가 필요한 시점에 유지되고 더 이상 필요하지 않은 시점에 해제되도록 해주는 두가지 방법을 제공한다. Objective-C 2.0에서 도입된 가비지 컬렉션은 프로그램에서 더 이상 사용하지 않는 객체를 자동적으로 추적하고 해제하여 메모리를 정리한다. Foundation은 전통적인 메모리 관리 방식도 함께 제공한다. 이 방식은 객체의 소유권 정책을 시행한다. NSObject 클래스와 프로토콜은 객체의 유지와 해제에 관한 메소드들을 정의하고 있다. NSAutoreleasePool 클래스에 정의되어 있는 자동해제 풀(Autorelease Pool)은 지연된 해제 매커니즘(delayed-release mechanism)을 구현하며 코코아 프로그램이 리턴하는 객체에 관해 일관적인 규칙을 가지도록 해준다. 가비지 컬렉션과 명시적인 메모리 관리에 대해서는 “Object Retention and Disposal”에서 자세히 다룬다.[note color=”#fffbb8″]iOS Note: iOS에서 실행되는 어플리케이션에서는 가비지 컬렉션을 사용할 수 없다.[/note]
  • Mutable class variants. Foundation 프레임워크에 있는 다수의 값 클래스와 컨테이너 클래스들은 불변 클래스의 가변 버전을 가진다. 가변 클래스는 항상 불변 클래스의 하위 클래스가 된다. 객체의 값이나 소유권을 동적으로 변경해야 한다면 가변 클래스의 인스턴스를 생성한다. 이 클래스는 불변 클래스로부터 상속되기 때문에 불변 형식을 받아들이는 메소드에 가변 인스턴스를 전달할 수 있다. 객체의 가변성에 대한 자세한 정보는 “Object Mutability”에서 다룬다.
  • Class clusters. 클래스 클러스터는 추상 클래스이며 우산 인터페이스(umbrella interface)로 동작하는 추상 클래스의 비공개 구상 하위클래스(private concrete subclass)의 모음이다. 컨텍스트(특히 객체를 생성하기 위해 사용한 메소드)에 따라 가장 적합한 클래스의 인스턴스가 리턴된다. 예를 들어, NSString과 NSMutableString은 서로 다른 저장소에 최적화된 다양한 비공개 하위 클래스들의 인스턴스를 제공하는 중개자의 역할을 한다. 지난 몇 년간 구상 클래스들은 어플리케이션에 영향을 주지 않고 여러번 변경되었다. 클래스 클러스터에 대한 자세한 정보는 “Class Clusters”에서 다룬다.
  • Notifications. 통지는 코코아의 주요한 설계 패턴이다. 이 패턴은 옵저버라고 하는 객체들이 다른 객체의 동작이나 사용자 이벤트 또는 시스템 이벤트 발생에 대한 알림을 받을 수 있도록 해주는 브로드캐스트 매커니즘을 기반으로 한다. 통지를 발생시키는 객체는 옵저버의 존재나 정보에 대해 알지 못할수도 있다. 통지에는 동기, 비동지, 분산 통지와 같은 다양한 형식이 존재한다. Foundation의 통지 매커니즘은 NSNotification, NSNotificationCenter, NSNotificationQueue, NSDistributedNotificationCenter 클래스를 통해 구현된다. 통지에 대한 상세한 정보는 “Notifications”에서 다룬다.

[/list]

 

Foundation Classes

Foundation 클래스 계층구조는 NSObject 프로토콜, NSCopying 프로토콜과 함께 객체의 기본 속성과 동작을 정의하고 있는 NSObject 클래스를 기초로한다. NSObject에 대한 상세한 정보와 객체의 기본 동작에 대한 내용은 “The Root Class”에서 다룬다.

Foundation 프레임워크의 나머지 부분은 연관된 클래스의 그룹과 몇가지 개별 클래스들로 구성되어 있다. 여기에는 문자열, 바이트 배열, 컬렉션 클래스와 같이 다른 객체들을 저장하기 위한 기본 데이터 형식들을 대표하는 클래스들과 날짜와 같은 시스템 정보를 나타내는 클래스와 포트, 스레드, 프로세스와 같은 시스템 요소들을 대표하는 클래스들이 존재한다. 그림 1-7에 있는 클래스 계층구조는 논리적인 그룹과 상속관계를 보여준다. 파란색 배경을 가진 클래스들은 OS X와 iOS 버전이 모두 존재하며, 회식 배경을 가진 클래스들은 OS X 버전만 존재한다.

Figure 1-7  The Foundation class hierarchy

Figure 1-7 The Foundation class hierarchy

Figure 1-7  The Foundation class hierarchy

Figure 1-7 The Foundation class hierarchy

Figure 1-7  The Foundation class hierarchy

Figure 1-7 The Foundation class hierarchy

이 도표들은 Foundation 프레임워크의 클래스들을 종류에 따라 논리적으로 그룹화하고 있다. 특히 중요한 것은 인스턴스가 값 객체이거나 컬렉션인 클래스들이다.

 

Value Objects

값 객체들은 문자열, 숫자, 날짜, 구조체, 포인터 등과 같은 다양한 기본형식의 값을 캡슐화한다. 이들은 값에 대한 접근을 처리하고 적절한 방식으로 값을 조작한다. 동일한 클래스 형식을 가지는 값 객체들의 값을 비교할 때에는 객체의 포인터 값이 아닌 캡슐화된 값이 비교된다. 값 객체는 다른 객체의 속성이 되는 경우가 많이 있다.

물론 프로그램에서 스칼라나 다른 기본 형식을 사용할 수도 있고, 많은 경우에 스칼라를 사용하는 것은 합리적인 것이다. 그러나 다른 상황에서는 이러한 값들을 객체로 감싸는 것이 필요하거나 유리할 수도 있다. 예를 들어, 값 객체는 객체이기 때문에 런타임에 클래스 형식을 알아내고, 전달 가능한 메시지를 판단하고 객체와 함께 수행할 수 있는 다른 작업들을 할 수 있다. 배열이나 딕셔너리와 같은 컬렉션 객체의 요소는 반드시 객체여야 한다. 대부분은 아니지만 문자열, 숫자, 날짜와 같은 값을 받아들이거나 리턴하는 많은 코코아 프레임워크의 메소드들이 해당 값을 객체로 캡슐화하는 것을 요구한다. (특히 문자열의 경우 항상 C 문자열이 아닌 NSString 객체를 사용해야 한다.)

일부 값 객체의 클래스들은 가변 버전과 불변 버전을 가지고 있다. 일례로, NSData 클래스와 NSMutableData 클래스가 있다. 불변 객체에 의해 캡슐화된 값은 생성 후에 변경될 수 없지만, 가변 객체에 의해 캡슐화된 값은 변경될 수 있다.

다음은 좀 더 중요한 값 객체들의 역할에 대해 설명한다.

[list style=”star”]

  • NSValue 클래스의 인스턴스는 스칼라 형식, 포인터, 구조체와 같은 하나의 ANSI C 또는 Objective-C 데이터 항목을 캡슐화한다.
  • NSValue의 하위 클래스는 NSNumber 클래스는 int, float, double와 같은 숫자 값을 담고 있는 객체를 인스턴스화한다.
  • NSData 클래스의 인스턴스는 이지미 데이터와 같은 바이트 스트림을 위한 객체지향 저장소를 제공한다. 이 클래스는 파일 시스템에 객체를 쓰고, 파일 시스템으로부터 다시 읽어오는 메소드들을 가지고 있다.
  • NSDate 클래스는 NSTimeZone, NSCalendar, NSDateComponents, NSLocale 클래스와 함께 시간, 날짜, 달력, 로케일을 나타내는 객체를 제공한다. 이들은 날짜와 시간의 차이를 계산하는 메소드, 다양한 형식으로 날짜와 시간을 출력하는 메소드, 위치에 기반한 시간과 날짜 조정을 위한 메소드를 제공한다.
  • NSString 클래스의 객체들은 일련의 유니코드 문자를 위한 객체지향 저장소를 제공하는 값 객체의 한 종류이다. NSString의 메소드들은 UTF-8이나 null로 끝나는 바이트 배열과 같은 문자열을 특정 인코딩으로 변환할 수 있다. 또한 문자열 검색, 조합, 비교, 파일 시스템 경로 조작을 위한 메소드도 제공한다. NSString은 NSData와 마찬가지로 문자열을 파일 시스템에 쓰고, 파일시스템에서 다시 읽어오는 메소드를 포함하고 있다.
    NSString 클래스는 몇가지 연관된 클래스를 가진다. NSScanner 클래스의 인스턴스를 통해 NSString 객체로부터 숫자나 단어를 추출할 수 있다. NSCharacterSet 클래스는 다양한 NSString, NSScanner 메소드에서 사용되는 문자셋을 나타낸다. NSAttributedString 클래스의 인스턴스인 속성 문자열(Attributed String)은 글꼴, 자간 등과 같이 연관된 속성을 가지는 문자의 범위를 관리한다.

[/list]

NSFormatter 클래스와 여기에서 파생된 클래스로부터 생성된 포멧터 객체들은 그 자체로 값 객체가 아니지만 값 객체와 관련된 중요한 기능을 수행한다. NSDate와 NSNumber 인스턴스와 같은 값 객체를 사용자 인터페이스에 표시할 용도로 사용되는 특정 문자열 표현으로 변환한다.

 

Collections

컬렉션은 다른 객체들을 특별한 정렬 방식으로 저장하는 객체이다. Foundation 프레임워크는 iOS와 OS X에서 모두 사용할 수 있는 세가지 주요한 컬렉션 클래스를 정의하고 있다. 바로 NSArray, NSDictionary, NSSet 클래스이다. 이러한 컬렉션 클래스들은 다른 값 클래스들과 마찬가지로 가변 버전과 불변 버전을 가진다. 예를 들어, 특정 수의 요소들을 담고 있는 NSArray 객체를 생성한 후에는 새로운 요소를 추가하거나 이미 존재하는 요소를 삭제할 수 없다. 이러한 작업을 하기 위해서는 NSMutableArray 클래스를 사용해야 한다.

세가지 주요한 컬렉션 클래스의 객체들은 몇가지 공통적인 특징과 요구사항을 가진다. 이들이 포함하는 항목은 반드시 객체여야 하며, 어떤 형식의 객체라도 사용할 수 있다. 컬렉션 객체는 값 객체와 마찬가지로 property list의 기본 구성요소이며, 다른 모든 객체들처럼 아카이브되거나 배포될 수 있다. 게다가 컬렉션 객체는 자신이 담고 있는 객체를 자동적으로 유지한다. 즉, 포함하는 객체에 대한 강한 참조를 유지한다. 가변 컬렉션으로부터 객체를 제거할 때, 객체는 해제(release)되고 이 객체를 요구하는 다른 객체가 존재하지 않는다면 제거(free)된다.

[note color=”#fffbb8″]Note: “retain”, “release” 그리고 이와 연관된 용어들은 코코아에서 객체의 메모리 관리를 나타낸다. 이와 관련된 중요한 내용은 “Object Retention and Disposal”에서 제공한다.[/note]

컬렉션 클래스들은 자신이 담고 있는 특정 객체에 접근할 수 있는 메소드를 제공한다. 또한, 특별한 열거   객체와 컬렉션을 열거하고 각 요소에 순차적으로 접근할 수 있는 언어수준의 지원이 존재한다.

주요한 컬렉션 클래스들은 그들이 사용하는 정렬 방식에 의해 구별된다.

[list style=”star”]

  • 배열(NSArray)은 컬렉션의 요소에 접근하기 위해 0부터 시작하는 인덱스를 사용하는 정렬된 컬렉션이다.
  • 딕셔너리(NSDictionary)는 키와 값의 쌍을 관리하는 컬렉션이다. 키는 값을 식별하는 객체이며, 값 또한 객체이다. 이러한 키-값 구조로 인해 딕셔너리에 포함된 요소들은 정렬되지 않는다. 딕셔너리 내부에서 키는 반드시 유일해야 한다. 일반적으로 키는 문자열 객체이지만, 복사될 수 있는 어떤 객체도 키가 될 수 있다.
  • 집합(NSSet)은 배열과 유사하지만 정렬되지 않은 저장소를 제공한다. 다시 말해 집합에 포함된 요소의 정렬은 중요하지 않다. NSSet 객체에 포함된 항목은 반드시 다른것들과 구별되는 것이어야 한다. 하지만 NSCountedSet 클래스의 인스턴스는 동일한 객체를 하나 이상 포함할 수도 있다.

[/list]

OS X의 Foundation 프레임워크는 몇가지 컬렉션 클래스를 추가로 가지고 있다. NSMapTable은 가변 딕셔너리와 유사한 컬렉션 클래스이다. 하지만 NSDictionary와 달리, 객체 뿐만 아니라 포인터도 포함할 수 있고, 자신이 포함하고 있는 객체에 대한 강한 참조가 아닌 약한 참조를 유지한다. NSPointerArray는 포인터와 NULL 값을 포함할 수 있는 배열로 요소에 대해 강한 참조나 약한 참조를 모두 유지할 수 있다. NSHashTable 클래스는 NSSet을 기반으로 만들어졌지만 함수 포인터를 포함할 수 있고 가비지 컬렉션 환경에서 약한 참조를 지원하기 위한 몇가지 다른 옵션들을 제공한다.

컬렉션 클래스와 객체에 대한 상세한 내용은 Collections Programming Topics에서 다룬다.

 

Other Categories of Foundation Classes

Foundation 프레임워크에 있는 나머지 클래스들은 그림 1-7에 있는 도표에 나와있는 것처럼 다양한 종류로 나뉘어 진다. 다음은 그림 1-7에 있는 주요한 클래스 종류에 대해 설명하고 있다.

[list style=”star”]

  • Operating-system services. 많은 Foundation 클래스들은 OS의 저수준 서비스들에 대한 접근을 용이하게 하는 동시에 OS의 특성을 신경쓰지 않아도 되도록 해준다. 예를 들어, NSProcessInfo는 어플리케이션이 실행되는 환경정보를 질의할 수 있게 해주고, NSHost는 네트워크 상에 있는 호스트 시스템의 이름과 주소를 얻어온다. NSTimer 객체를 통해 특정 주기마다 다른 객체에 메시지를 보낼수도 있으며, NSRunLoop는 어플리케이션이나 다른 형식의 프로그램 입력 소스를 관리할 수 있도록 해준다. NSUserDefaults는 전역 시스템 데이터베이스와 사용자별 기본 값을 저장하는데 사용되는 프로그래밍 인터페이스를 제공한다.

File system and URL. NSFileManager는 파일의 생성, 이름변경, 삭제, 이동과 같은 파일 조작에 관한 일관적인 인터페이스를 제공한다. NSFileHandle은 파일 내용 탐색과 같은 저수준의 파일 조작을 가능하게 해준다. NSBundle은 번들에 저장되어 있는 리소스를 검색하고, 이들 중 일부를 동적으로 읽을 수 있다. NSURL 클래스와 NSURL…으로 시작하는 클래스들을 통해 URL에 있는 데이터 소스를 표현하고, 접근하고 관리할 수 있다.

Concurrency. NSThread는 다중 스레드 프로그램을 생성할 수 있게 해주며 다양한 잠금 클래스들은 경합하는 스레드에 의한 프로세스 자원 접근을 제어할 수 있는 매커니즘을 제공한다. NSOperation과 NSOperationQueue를 통해 우선순위와 의존순서에 따라 다중 작업을 수행할 수 있다. NSTask를 통해 자식 프로세스의 진행상황을 감시하고 작업을 수행하기 위해 자식 프로세스를 분기할 수 있다.

Interprocess communication. 이 범주에 속하는 대부분의 클래스들은 다양한 형태의 시스템 포트, 소켓, 네임 서버들을 나타내며, 저수준의 IPC를 구현하는데 유용하다. NSPipe는 프로세스 사이의 단방향 통신 채널인 BSD 파이프를 나타낸다.

[note color=”#fffbb8″]iOS Note: iOS 버전 Foundation에는 네임서버 클래스가 존재하지 않는다.[/note]

Networking. NSNetService, NSNetServiceBrowser 클래스는 봉주르(Bonjour)라고 하는 무설정 네트워킹 아키텍처(zero-configuration networking architecture)를 제공한다. 봉주르는 IP 네트워크 상에서 서비스를 공개하고 검색하는데 사용되는 강력한 시스템이다.

  • Notifications. 통지 클래스에 대한 개요는 “Foundation Paradigms and Policies”에서 볼 수 있다.
  • Archiving and serialization. 이 범주에 속하는 클래스들은 객체의 배포(distribution)와 영속화(persistence)를 가능하게 해준다. NSCoder and its subclasses, along with the NSCoding protocol, represent the data an object contains in an architecture-independent way by allowing class information to be stored along with the data. NSKeyedArchiver와 NSKeyedUnarchiver는 인코딩 순서에 의존하지 않는 방식으로 객체와 스칼라 값을 인코딩하고 디코딩 할 수 있는 메소드를 제공한다.
  • Objective-C language services. NSException과 NSAssertionHandler 클래스는 코드에서 예외를 처리하고 assertion을 수행하기 위한 객체지향적인 방법을 제공한다. NSInvocation 객체는 프로그램에서 저장할 수 있고 나중에 또다른 객체에서 메시지를 호출하는데 사용하는 Objective-C 메시지에 대한 정적 표현이다. 이것은 undo 관리자와 분산 객체 시스템에서 사용된다. NSMethodSignature 객체는 메소드의 형식정보를 기록하며 메시지 포워딩에 사용된다. NSClassDescription은 클래스의 관계(relationship)과 속성들을 정의하고 질의하는데 사용되는 추상 클래스이다.
  • XML processing. 양 플랫폼의 Foundation은 모두 XML데이터를 이벤트 기반으로 처리할 수 있도록 해주는 스트리밍 파서의 객체지향 구현인 NSXMLParser 클래스를 가지고 있다. OS X의 Foundation 은 NSXML로 시작하는 클래스들을 포함하고 있다. 이러한 클래스의 객체들은 XML 문서를 계층적인 트리 구조로 나타낸다. 이러한 접근방식은 구조를 질의하고 노드를 조작할 수 있도록 해준다. NSXML 클래스들은 XQuery, XPath, XInclude, XSLT, DTD, XHTML과 같은 다양한 XML 관련 기술과 표준을 지원한다.
  • Predicates and expressions. NSPredicate, NSCompoundPredicate, NSComparisonPredicate와 같은 술어(Predicate) 클래스들은 객체의 fetch와 filter를 제약하는 논리적인 상태를 캡슐화한다. NSExpression objects represent expressions in a predicate.

[/list]

iOS의 Foundation 프레임워크는 OS X 버전의 하위 집합이다. 다음과 같은 범주에 속하는 클래스들은 OS X버전의 Foundation에서만 제공된다.

[list style=”star”]

  • Spotlight queries. NSMetadataItem, NSMetadataQuery 클래스, 그리고 이와 연관된 쿼리 클래스들은 파일 시스템 메타데이터를 캡슐화하고 메타데이터 질의를 가능하게 해준다.
  • Scripting. 이 범주에 속하는 클래스들은 프로그램이 AppleScript 스크립트나 Apple 이벤트 명령에 응답할 수 있도록 해준다.
  • Distributed objects. 분산 객체 클래스들은 동일한 컴퓨터나 네트워크 상의 다른 컴퓨터상에 존재하는 프로세스 사이의 통신에 사용한다. 이 클래스들 중 NSDistantObject와 NSProtocolChecker 클래스는 다른 코코아 클래스와 달리 NSProxy 클래스를 최상위 클래스로 가진다.

[/list]

 

AppKit (OS X)

AppKit은 창, 대화상자, 버튼, 메뉴, 스크롤러, 텍스트 필드 등과 같이 OS X에서 이벤트 기반의 그래픽 사용자 인터페이스를 구현하기 위해 필요한 모든 객체들을 가지고 있는 프레임워크이다. AppKit은 화면에 객체를 효율적으로 그리며, 하드웨어 디바이스, 스크린 버퍼와 통신하고 그리기 작업 전에 스크린 영역을 삭제하고 뷰를 잘라내는 등 모든 상세한 작업들을 대신 처리해준다. 처음에는 AppKit에 있는 다수의 클래스들이 벅차 보일수도 있다. 하지만 대부분의 AppKit 클래스들은 간접적으로 사용하게 되는 지원 클래스들이다. 어떠한 단계에서 AppKit을 사용할지 선택할 수도 있다.

[list style=”star”]

  • 사용자 인터페이스 객체와 어플리케이션의 컨트롤러 객체 사이의 연결을 생성하기 위해 Interface Builder를 사용한다.
  • 사용자 인터페이스를 코드를 통해 제어한다. 이 경우 AppKit 클래스와 프로토콜에 더 익숙해야 한다. 예를 들어, 사용자가 하나의 창에서 다른 창으로 아이콘을 드래그 할 수 있도록 하려면 NSDragging…류의 프로토콜에 익숙해야 하며 이를 통해 약간의 프로그래밍을 해야 한다.
  • NSView 또는 다른 클래스를 상속하여 자신만의 객체를 직접 구현한다. NSView의 하위클래스를 작성할 때 그래픽 함수를 통해 그리기 메소드들을 직접 작성하게 된다. 서브클래싱은 AppKit의 동작 방식에 대한 깊은 이해를 필요로한다.

[/list]

 

Overview of the AppKit Framework

AppKit 프레임워크는 125개 이상의 클래스와 프로토콜로 구성되어 있다. 모든 클래스들은 Foundation 프레임워크에 있는 NSObject 클래스로부터 상속된다. 그림 1-8에 있는 도표는 AppKit 클래스들의 상속관계를 보여준다.

Figure 1-8  AppKit class hierarchy—Objective-C

Figure 1-8 AppKit class hierarchy—Objective-C

Figure 1-8  AppKit class hierarchy—Objective-C

Figure 1-8 AppKit class hierarchy—Objective-C

그림에서 볼 수 있듯이 AppKit의 상속 트리는 광범위 하지만 깊이가 꽤 얕기도 하다. 계층구조에서 가장 깊은 단계의 클래스들은 최상위 클래스로부터 단지 다섯개의 상위 클래스만을 가지며 대부분의 클래스들은 이보다 더 적은 수의 상위 클래스를 가진다. 이 계층구조 트리에서 몇가지 주요한 가지(branch)는 특히 흥미롭다.

AppKit에서 가장 큰 가지의 최상위 클래스는 NSResponder 클래스이다. 이 클래스는 응답 체인(responder chain, 사용자 이벤트에 응답하는 객체의 정렬된 목록)을 정의한다. 사용자가 마우스 버튼을 클릭하거나 키를 누를 때 생성된 이벤트는 자신을 처리할 수 있는 객체를 찾을 때까지 응답 체인을 따라 전달된다. 이벤트를 처리하는 객체들은 반드시 NSResponder 클래스를 상속해야 한다. NSApplication, NSWindow, NSView와 같은 AppKit의 주요한 클래스들은 NSResponder 클래스를 상속하고 있다.

AppKit에서 두번째로 큰 가지는 NSCell로부터 내려온다. 이 클래스 그룹에서 주목할 만한 것은 이들이 NSControl 클래스로부터 상속된 것과 약간 닮았다는 것이다. AppKit은 사용자의 액션에 반응하는 사용자 인터페이스 객체에 대해 컨트롤 객체와 셀 객체 사이의 역할을 구분하는 아키텍처를 사용한다. NSControl 클래스와 NSCell 클래스, 그리고 여기에서 파생되는 클래스들은 버튼, 슬라이더, 브라우저와 같은 공통적인 사용자 인터페이스 객체를 정의하고 있다. 대부분의 제어 객체들은 그리기와 이벤터 처리를 구현하고 있는 하나 이상의 셀 객체와 연관되어 있다. 예를 들어, 버튼은 NSButton 객체와 NSButtonCell 객체를 모두 포함한다.

컨트롤과 셀들은 타겟-엑션 매커니즘이라고 하는 AppKit의 중요한 설계 패턴을 기반으로하는 매커니즘을 구현한다. 셀은 사용자가 자신을 클릭할 때 특정 객체로 전달되어야 하는 메시지를 식별하는 정보를 가질 수 있다. 사용자가 컨트롤을 조작할 때, 컨트롤을 자신의 셀에서 필요한 정보를 추출한 다음 대상 객체로 액션 메시지를 보낸다. 타겟-엑션은 대상 객체가 무엇이며 어떤 메소드가 호출되어야 하는지를 지정함으로써 사용자 엑션에 목적을 부여할 수 있도록 해준다. 일반적으로 Interface Builder를 통해 컨트롤 객체를 어플리케이션 객체나 다른 객체로 Control키는 누른채 드래깅하는 방식으로 타겟과 엑션을 설정한다. 코드를 통해서도 타겟과 엑션을 설정할 수 있다.

또 다른 중요한 설계 패턴은 델리게이션(Delegation)이다. 텍스트 필드와 테이블 뷰와 같이 사용자 인터페이스에 있는 많은 객체들은 델리게이트를 정의하고 있다. 델리게이트는 대상 객체(delegating object) 대신 동작하거나 대상 객체와 협력하는 객체이다. 따라서 이 객체는 사용자 인터페이스 기능에 어플리케이션에 특화된 로직을 전달할 수 있다. 델리게이터, 타겟-엑션, 그리고 AppKit의 또 다른 패러다임과 매커니즘에 대한 자세한 내용은 “Communicating with Objects”에서 다룬다. 이러한 패러다임과 매커니즘들이 사용하는 설계 패턴에 대한 내용은 “Cocoa Design Patterns”에서 설명한다.

OS X 10.5 버전 이후 시스템의 일반적인 특징 중 한가지는 resolution independence(해상도 독립)이다. 화면의 해상도는 코드를 통해 수행되는 그리기로부터 분리되어 있다. 시스템은 컨텐츠를 화면에 렌더링 하기 위해서 자동적으로 크기를 변경한다. AppKit 클래스들은 사용자 인터페이스 객체에서 resolution independence를 지원한다. 하지만 어플리케이션에서 resolution independence의 이점을 활용하려면 높은 해상도의 이미지를 제공하거나 그리기 코드가 현재 비율을 고려하도록 약간의 수정을 가해야 한다.

이어지는 섹션은 AppKit 프레임워크와 이 프레임워크에 있는 클래스, 프로토콜의 몇가지 기능적, 구조적인 요소에 대해 간략하게 설명한다. 이어지는 내용들은 그림 1-8에 있는 클래스 계층구조에 따라 클래스들을 그룹으로 묶고 있다.

 

General User-Interface Classes

AppKit은 사용자 인터페이스의 전반적인 기능을 위해 다음과 같은 클래스들을 제공한다.

[list style=”star”]

  • The global application object. 메인 이벤트 루프를 제어하기 위해서 NSApplication의 싱글톤 인스턴스를 사용하는 모든 어플리케이션은 어플리케이션의 창과 메뉴를 유지하고, 적절한 객체로 이벤트를 보내며, 최상위 레벨의 자동해제 풀(autorelease pool)을 설정하고 어플리케이션 수준의 이벤트에 대한 통지를 전달받는다. NSApplication 객체는 어플리케이션에서 특정 이벤트가 발생할 때 통지를 받는 델리게이트를 가진다. NSApplication 객체의 델리게이트를 설정하고 델리게이트 메소드를 구현함으로써 NSApplication을 상속하는 클래스를 만들지 않고도 어플리케이션의 동작을 수정할 수 있다.
  • Windows and views. NSWindow, NSView와 같은 창과 뷰 컨트롤러들도 NSResponder를 상속하며 사용자의 엑션에 반응하도록 설계되었다. NSApplication 객체는 NSWindow 객체의 목록을 유지하고, 각각의 NSWindow 객체는 NSView 객체들의 계층구조를 유지한다. 뷰 계층구조는 창 내에서 이벤트를 처리하고 그리기를 수행하는데 사용된다. NSWindow 객체는 창 수준의 이벤트들을 처리하고, 다른 이벤트들은 자신의 뷰로 전달하며 뷰가 그려지는 영역을 제공한다. 또한 창의 동작을 수정할 수 있는 델리게이트로 가지고 있다.
    OS X 10.5 버전부터 AppKit의 창과 뷰 클래스들은 향상된 에니메이션 기능을 지원한다.
    NSView는 창에 표시되는 모든 객체의 부모클래스이다. 모든 자식클래스들은 그래픽 함수를 사용해서 그리기 메소드를 구현한다. drawRect:는 새로운 NSView를 생성할 때 재정의 하게되는 기본적인 메소드이다.
  • Controller classes for Cocoa bindings. 추상 클래스인 NSController와 이 클래스를 상속하고 있는 구상 클래스(concrete subclass)인 NSObjectController, NSArrayController, NSDictionaryController, NSTreeController는 코코아 바인딩 구현의 한 부분이다. 이 기술은 객체에 저장되어 있는 어플리케이션 데이터와 사용자 인터페이스에 표시되어 있는 해당 데이터를 자동으로 동기화한다. 이러한 형식의 컨트롤러 객체에 대한 설명은 “The Model-View-Controller Design Pattern”에서 제공한다.
  • Panels (dialogs). NSPanel 클래스는 임시적이거나 전역적이거나 긴급한 정보를 표시하는데 사용하는 클래스로 NSWindow를 상속한다. 예를 들어, 오류 메시지를 표시하거나 주목할 만한 상황이나 일반적이지 않은 상황에서 사용자의 응답을 얻기위해 NSWindow의 인스턴스가 아닌 NSPanel의 인스턴스를 사용할 것이다. AppKit은 문서를 열거나 저장하고 출력하는데 사용되는 Save, Open, Print 대화상자와 같은 몇가지 공통 대화상자를 구현하고 있다. 이러한 대화상자를 사용하면 어플리케이션 전반에 사용되는 일반적인 작업에 대해 일관적인 룩앤필을 제공할 수 있다.
  • Menus and cursors. NSMenu, NSMenuItem, NSCursor 클래스는 어플리케이션이 사용자에게 보여주는 메뉴와 커서의 모양과 동작을 정의한다.
  • Grouping and scrolling views. NSBox, NSScrollView, NSSplitView 클래스는 창에 있는 다른 뷰 객체나 뷰의 컬렉션에 그래픽 악세사리를 제공한다. NSBox 클래스를 통해 창에 있는 요소들을 그룹으로 묶고 전체 그룹을 감싸는 외곽선을 그릴 수 있다. NSScrollView 클래스와 이 클래스의 도우미 클래스(helper class)인 NSClipView는 스크롤 매커니즘과 스크롤을 시작하고 제어할 수 있도록 해주는 그래픽 객체들을 제공한다. NSRulerView 클래스는 스크롤뷰에 자와 마커를 추가할 수 있도록 해준다.
  • Table views and outline views. NSTableView 클래스는 데이터를 행과 열에 표시한다. NSTableView는 데이터베이스 레코드를 표시하는데 적합하지만 이러한 용도로 한정되지는 않는다. 사용자는 개별 셀을 편집하고 열(column)의 순서를 변경할 수 있다. NSTableView 객체의 델리게이트와 데이터 소스 객체를 설정하여 이 객체의 내용과 동작을 제어한다. NSTableView를 상속하는 NSOutlineView의 인스턴스인 아웃라인 뷰는 테이블 형식의 데이터를 표시하는 또 다른 방식을 제공한다.

[/list]

 

Text and Fonts

코코아 텍스트 시스템은 OS X 10.5 버전에서 도입된 Core Text 프레임워크를 기반으로 한다. Core Text 프레임워크는 텍스트 조작을 위한 현대적이고 저수준의 고성능 기술을 제공한다. 코코아 텍스트 시스템을 사용하고 있다면 Core Text를 직접 사용해야 하는 경우는 드물다.

NSTextField 클래스는 단순한 형태의 편집가능한 텍스트 입력 필드를 구현하고, NSTextView 클래스는 큰 텍스트를 위한 좀 더 광범위한 편집 기능을 제공한다.

NSText 추상 클래스의 자식 클래스인 NSTextView는 확장 텍스트 시스템과 관련된 인터페이스들을 정의하고 있다. NSTextView는 리치 텍스트, 첨부(attachment), 입력 관리, 키 바인딩, marked text attributes를 지원한다. NSTextView는 Fonts 창, Font 메뉴, 눈금자(ruler)와 문단 스타일, Services 기능, 클립보드를 사용할 수 있다. 또한 델리게이션(delegation)과 통지를 통해 동작을 수정할 수도 있다. 그러므로 NSTextView를 서브클래싱해야 하는 경우는 드물다. Interface Builder의 Library 창에는 NSTextField, NSForm, NSScrollView와 같이 이미 NSTextView를 포함하고 있는 객체들이 존재하기 때문에 NSTextView의 인스턴스를 코드를 통해 생성하는 경우도 거의 없다.

NSTextStorage, NSLayoutManager, NSTextContainer 클래스와 이들과 연관된 클래스들을 통해 좀 더 강력하고 창의적으로 텍스트를 조작할 수도 있다. 코코아 텍스트 시스템은 목록 선택, 테이블 선택, 인접하지 않는 항목의 선택도 지원한다.

NSFont, NSFontManager 클래스는 폰트 집합(font family), 크기, 변형 스타일(variations)을 캡슐화하고 관리한다. NSFont 클래스는 각 개별 폰트에 대한 단일 객체를 정의한다. 이러한 객체들을 많은 데이터를 표한할 수 있기 때문에 어플리케이션에 있는 모든 객체에 의해 공유된다. NSFontPanel 클래스는 사용자에게 표시되는 Fonts 창을 정의한다.

 

Graphics and Colors

NSImage, NSImageRep 클래스는 그래픽 데이터를 캡슐화하여 파일에 저장된 이미지와 화면에 표시된 이미지에 쉽고 효율적으로 접근할 수 있도록 해준다. NSImageRep의 하위 클래스들은 특정 형식의 원본 데이터로부터 이미지를 그리는 방식에 대해 알고 있다. NSImage 클래스는 동일한 이미지에 대한 다양한 표현을 제공하며 캐싱과 같은 동작들을 제공한다. 코코아의 이미지와 그리기 능력은 Core Image 프레임워크에 포함되어 있다.

색상은 NSColor, NSColorSpace, NSColorPanel, NSColorList, NSColorPicker, NSColorWell 클래스를 통해 지원된다. NSColor와 NSColorSpace 클래스는 사용자정의 색상을 포함한 풍부한 색상 형식과 표현을 지원한다. 다른 클래스들은 대부분 인터페이스 클래스이다. 이들은 사용자가 색상을 선택하고 적용할 수 있도록 해주는 패널과 뷰를 정의하고 제공한다.

NSGraphicsContext, NSBezierPath, NSAffineTransform 클래스는 vector drawing을 가능하게 해주며 크기 변경(scaling), 회전(rotation), 평행 이동(translation)과 같은 변환(graphical transformations)을 지원한다.

 

Printing and Faxing

NSPrinter, NSPrintPanel, NSPageLayout, NSPrintInfo 클래스는 어플리케이션이 자신의 창과 뷰에 표시하고 있는 정보를 출력하고 팩스를 통해 전송하는 수단을 제공하기 위해 서로 협력한다. 또한 NSView 객체를 PDF 형식으로 만들수도 있다.

 

Document and File-System Support

NSFileWrapper 클래스를 통해 디스크에 있는 파일이나 디렉토리에 해당하는 객체를 생성할 수 있다. NSFileWrapper는 파일의 내용을 표시하거나, 변경하거나, 다른 어플리케이션으로 전송할 수 있도록 이 내용을 메모리에 유지한다. 또한, 드래그되는 파일이나 첨부파일로 표시되는 파일을 위한 아이콘을 제공한다. Foundation 프레임워크에 있는 NSFileManager를 사용해서 파일과 디렉토리의 내용에 접근하고 이들을 열거할 수 있다. NSOpenPanel, NSSavePanel 클래스는 친숙하고 편리한 사용자 인터페이스를 제공한다.

NSDocumentController, NSDocument, NSWindowController 클래스는 문서 기반 어플리케이션의 생성을 위한 아키텍처를 정의한다. 이들은 문서를 저장하고, 열고, 되돌리고, 닫고, 관리하기 위한 내장 기능 또는 쉽게 가져올 수 있는 기능들을 가지고 있다.

 

Internationalization and Character Input Support

어플리케이션의 하나 이상의 지역에서 사용된다면, 어플리케이션의 리소스들은 언어, 지역, 문화권에 따라 사용자화 되거나 지역화 되어야 할지도 모른다. 예를 들어, 어플리케이션이 일본어, 영어, 프랑스어, 독일어 버전별로 각각의 문자열, 아이콘, nib 파일, 도움말을 가지고 있어야 할 수도 있다. 특정 언어에 국한된 리소스 파일들은 번들 디렉토리의 하위 디렉토리에 함께 그룹으로 저장된다. 일반적으로 Interface Builder를 통해 지역화 리소스 파일들을 설정한다. Internationalization Programming Topic에서 코코아의 국제화 기능에 대한 더 많은 정보를 얻을 수 있다.

NSInputServer, NSInputManager 클래스는 NSTextInput 프로토콜과 함께 텍스트 입력 관리 시스템에 대한 접근을 제공한다. 이 시스템은 다양한 키보드를 통해 생성되는 키입력을 해석하고 적절한 문자 또는 Control 키 이벤트를 텍스트 뷰 객체로 전달한다. (보통 텍스트 클래스들이 이러한 클래스들을 처리하고 있기 때문에 직접 처리할 필요는 없다.)

 

Operating-System Services

AppKit은 다음과 같은 기능을 구현하고 있는 클래스를 통해 어플리케이션을 위한 OS 지원을 제공한다.

[list style=”star”]

  • 다른 어플리케이션과의 데이터 공유. NSPasteboard 클래스는 pasteboard(또는 클립보드)를 정의한다. 이것은 어플리케이션에서 복사된 데이터를 위한 저장소로, 저장된 데이터는 모든 어플리케이션에서 사용될 수 있다. NSPasteboard는 친숙한 자르기/복사 & 붙어넣기 작업을 구현하고 있다.
  • Dragging. 커스텀 뷰 객체들은 약간의 프로그래밍을 통해 드래그&드롭 기능을 가질 수 있다. 이러한 드래깅 매커니즘의 일원이 되는 객체들은 NSDragging..으로 시작하는 프로토콜들을 따른다. 드래그 할 수 있는 객체들은 NSDraggingSource 프로토콜을 따르고, 목적지 객체들(receivers of a drop)은 NSDraggingDestination 프로토콜을 따른다. AppKit은 커서를 추적하고 드래그된 이미지를 표시하는 방식에 대한 상세 구현은 공개하지 않는다.
  • Spell Checking. NSSpellServer 클래스는 철자 검색 서비스를 정의하고 이것을 다른 어플리케이션에 서비스로 제공할 수 있도록 해준다. 어플리케이션과 철자 검색 서비스를 연결할 때는 NSSpellChecker 클래스를 사용한다. NSIgnoreMisspelledWords, NSChangeSpelling 프로토콜은 철자 검색 매커니즘을 지원한다.

[/list]

 

Interface Builder Support

추상 클래스인 NSNibConnector와 이 클래스의 구상 클래스인 NSNibControlConnector와 NSNibOutletConnector는 Interface Builder에서 연결을 나타낸다. NSNibControlConnector는 엑션 연결을 관리하고 NSNibOutletConnector는 아웃렛 연결을 관리한다.

 

UIKit (iOS)

iOS에 있는 UIKit 프레임워크는 OS X에 있는 AppKit 프레임워크의 자매 프레임워크이다. 이 프레임워크의 사용목적은 어플리케이션이 자신의 사용자 인터페이스를 구성하고 관리하는데 필요한 모든 클래스를 제공하는 것으로 AppKit의 사용목적과 본질적으로 동일하다. 하지만, 프레임워크가 이러한 목적을 현실화하는 방식에 있어서는 큰 차이가 존재한다.

큰 차이점 중 하나는 iOS의 사용자 인터페이스에 보여지는 객체들의 모습이나 동작 방식이 OS X의 그것과 다르다는 것이다. 텍스트 뷰, 버튼, 테이블 뷰와 같은 것들이 이러한 예에 속한다. 또한, 두 플랫폼의 이벤트 처리 모델과 그리기 모델은 상당한 차이점을 가지고 있다. 이어지는 섹션에서는 이러한 차이점을 가지고 있는 이유와 또 다른 차이점들에 대해 설명한다.

어플리케이션의 사용자 인터페이스에 UIKit 객체를 추가할 때에는 세가지 방식을 사용할 수 있다.

[list style=”star”]

  • Interface Builder 어플리케이션을 통해 객체 라이브러리에서 창, 뷰와 같은 객체들을 드래그한다.
  • 코드를 통해 프레임워크 객체를 생성하고 구성한다.
  • UIView 클래스나 UIView 클래스로부터 상속되는 클래스를 서브클래싱하여 커스텀 사용자 인터페이스 객체를 구현한다.

[/list]

 

Overview of UIKit Classes

AppKit과 마찬가지로 UIKit 프레임워크의 클래스들은 NSObject로부터 상속된다. 그림 1-9는 UIKit 프레임워크의 클래스들과 상속관계를 보여준다.

Figure 1-9  UIKit class hierarchy

Figure 1-9 UIKit class hierarchy

AppKit과 마찬가지로, UIKit 클래스 계층구조에서 가장 큰 가지의 최상위 클래스는 base responder 클래스이다. UIResponder 클래스는 이벤트 처리 메소드와 응답 체인을 위한 인터페이스와 기본 동작을 정의한다. UIKit은 사용자가 테이블 뷰를 스크롤하거나 가상 키보드를 문자를 입력할 때 이벤트를 생성하며, 이 이벤트는 자신을 처리할 수 있는 객체를 찾을 때까지 응답 체인(responder chain)을 따라 전달된다. NSApplication, UIWindow, UIView와 같은 중요한 객체들은 모두 UIResponder를 직간접적으로 상속한다.

UIKit은 AppKit과 달리 셀을 사용하지 않는다. UIKit에 있는 컨트롤들은 자신의 주요 역할(대상 객체로 메시지 보내기)을 수행하기 위해 셀을 필요로 하지 않는다. UIKit이 타겟-엑션 매커니즘을 구현하는 방식은 AppKit이 구현하는 방식과 다르다. UIControl 클래스는 컨트롤을 위한 이벤트 형식을 정의한다. 예를 들어, 버튼이 대상 객체로 액션 메시지를 보내도록 하려면, UIControl에서 제공하는 메소드를 호출하여 하나 이상의 컨트롤 이벤트 형식을 액션과 대상에 연결한다. 연결된 이벤트 중 하나가 발생하면 컨트롤은 액션 메시지를 보낸다.

UIKit 프레임워크는 델리게이션을 상당히 많이 사용한다. 하지만 UIKit의 델리게이션 구현은 AppKit의 구현과 다르다. UIKit은 비공식 프로토콜 대신 일부 프로토콜 메소드를 선택적인 메소드를 지정할 수 있는 공식 프로토콜을 사용한다.

 

Application Coordination

iOS에서 실행중인 각 어플리케이션은 단일 어플리케이션 객체를 통해 관리되며, 이 객체는 전역 NSApplication 객체와 거의 유사한 역할을 한다. UIApplication 객체는 메인 이벤트 루프를 제어하고, 어플리케이션의 창과 뷰를 유지하며, 입력되는 이벤트를 적절한 응답 객체로 전달한다.

또한 UIApplication 객체는 시스템 수준의 이벤트와 어플리케이션 수준의 이벤트에 대한 통지를 받는다. 이 중 대부분은 어플리케이션이 시작되거나 종료될 때, 메모리 부족 경고와 시간 변화에 응답하기 위해서, 그리고 다른 작업들을 처리하기 위해 어플리케이션에 특화된 동작을 삽입할 수 있도록 UIApplication 객체의 델리게이트로 전달된다.

 

Differences in Event and Drawing Models

OS X에서는 마우스와 키보드가 대부분의 사용자 이벤트를 만들어 낸다. AppKit은 NSEvent 객체를 통해 이러한 이벤트들을 캡슐화한다. 하지만 iOS에서 이벤트를 만들어 내는것은 화면 위에서 움직이는 사용자의 손가락이다. UIKit은 UIEvent라는 클래스를 통해 이런 이벤트들을 나타낸다. 손가락 터치는 마우스 클릭과 성질이 다르므로 일정 기간 동안 발생하는 두개 이상의 터치는 핀치 제스처와 같은 별개의 이벤트를 만들어 낼 수도 있다. 따라서 UIEvent 객체는 손가락 터치를 나타내는 하나 이상의 객체를 포함한다. 두 플랫폼에서 이벤트를 처리할 수 있는 객체로 이벤트를 배포하거나 전달하는 방식은 거의 유사하다. 하지만, 객체는 이벤트를 처리하기 위해 이벤트에 포함되어 있는 터치의 순서를 고려해야 한다.

또한 UIKit은 터치를 제스처로 검출하는 작업을 자동화하는 객체인 제스처 인식기(gesture recognizer)를 가지고 있다. 제스처 인식기는 일련의 터치를 분석한 후, 자신이 정의하고 있는 제스처로 인식될 때 지정된 대상으로 액션 메시지를 보낸다. UIKit은 tap, swipe, rotate, pan과 같은 제스처를 처리하기 위해 미리 제작된 제스처 인식기들을 제공한다. 어플리케이션에 특화된 제스처를 인식하는 커스텀 제스처 인식기를 만들수도 있다.

AppKit과 UIKit의 그리기 방식은 유사하다. 에니메이션은 UIKit 그리기 구현으로 통합되었다. 그리기에 대한 직접적인 지원은 AppKit에 비해 약간 제한적이다. 프레임워크는 베지어 곡선, PDF 생성, 단순한 라인과 사각형 그리기 등을 수행할 수 있는 클래스와 함수들을 제공한다. UIColor 객체를 통해 현재 그래픽 컨텍스트에 있는 색상을 설정하고, UIImage 객체를 통해 이미지를 보여주고 캡슐화 할 수 있다. 더욱 정교한 그리기를 사용하려면 반드시 Core Graphics나 OpenGL ES 프레임워크를 사용해야 한다.

 

General User-Interface Classes

iOS의 사용자 인터페이스 있는 객체들은 OS X의 사용자 인터페이스와 시각적인 차이를 가진다. iOS에 있는 사용자 인터페이스 객체들은 디바이스의 특성으로 인해 반드시 터치를 받아들일 수 있을만큼 커야함과 동시에 실제 화면 영역을 가능한 효율적으로 사용해야 한다. 때때로 이러한 객체들은 이전과는 전혀 다른 종류의 시각적, 촉각적 비유를 기반으로 하기도 한다. 일례로 UIKit 프레임워크와 AppKit 프레임워크에 각각 정의되어 있는 클래스로부터 생성된 날짜 선택기(date picker) 객체가 있다. OS X의 날짜 선택기의 모양은 다음과 같다.

datepicker_osx

이 날짜 선택기는 날짜 구성요소를 증감시키는데 사용되는 두개의 작은 영역을 가지고 있으므로 마우스 포인터를 통한 조작에 적합하다. 이와 대조적으로 iOS 어플리케이션의 날짜 선택기는 다음과 같은 모양이다.

datepicker_a

이 날짜 선택기는 터치 입력에 더 적합하다. 사용자는 각 열을 스와이프(swipe)하여 새로운 값을 선택할 수 있다.

AppKit과 마찬가지로 다수의 UIKit 클래스들은 기능적인 그룹으로 구분되어 있다.

[list style=”star”]

  • Controls. UIControl의 하위 클래스들은 사용자들이 자신의 의도를 어플리케이션에 전달할 수 있도록 해주는 객체들을 생성한다. 표준 버튼 객체(UIButton), 슬라이더 객체(UISlider) 뿐만 아니라 스위치를 표현하는 컨트롤(UISwitch), 다차원 값을 선택하는데 사용할 수 있는 spinning-wheel 컨트롤(UIPickerView), 문서를 페이지 방식으로 처리하는데 사용되는 컨트롤(UIPageControl) 등 다양한 컨트롤들이 존재한다.
  • Modal views. UIModalView에서 파생된 UIActionSheet와 UIAlertView 클래스는 특정 뷰나 윈도우에 부착된 sheet 형태 또는 어디에도 부착되지 않은 경고창 형태의 메시지를 표시하는데 사용된다. iPad에서는 액션시트 대신 팝오버 뷰(UIPopoverController)를 사용할 수 있다.
  • Scroll views. UIScrollView 클래스는 터치에 따라 뷰의 내용을 스크롤 할 수 있도록 해준다. 스크롤 뷰는 사용자가 스크롤을 진행하는 동안 문서내의 위치를 나타내는 스크롤바를 표시한다. 테이블뷰, 텍스트뷰, 웹뷰는 UIScrollView로부터 파생된 객체들이다.
  • Toolbars, navigation bars, split views, and view controllers. UIViewController 클래스의 뷰의 관리를 위한 기본 클래스이다. 뷰 컨트롤러는 뷰의 생성과 감시(observing), overlaying, 회전 처리, 메모리 부족 경고 처리를 위한 메소드들을 제공한다. UIKit은 툴바, 네비게이션 바, 이미지 피커를 관리하는데 사용되는 UIViewController 구상 하위클래스들을 포함하고 있다.
  • 툴바와 네비게이션 바를 함께 사용하는 어플리케이션은 화면의 메인뷰와 연관된 동작을 관리한다. 일반적으로 툴바는 메인뷰의 하단에, 네비게이션 바는 상단에 위치한다. 툴바 객체(UIToolBar)는 어플리케이션의 모드나 뷰를 전환하는데 사용한다. 또한 현재 뷰와 연관된 특정 액션을 수행하는 기능들을 표시하는 용도로 사용할 수도 있다. 네비게이션 바(UINavigationBar)는 어플리케이션에 있는 일련의 윈도우나 뷰를 관리하기 위해 사용하며, 실제로 “drill down” 방식으로 어플리케이션에 정의되어 있는 객체의 계층구조를 탐색한다. 예를 들어, Mail 어플리케이션은 계정화면에서 메일함으로 이동하고, 여기에서 다시 개별 메일로 이동하기 위해서 네비게이션 바를 사용한다. iPad에서는 UISplitViewController 객체를 통해 master-detail 인터페이스를 제공할 수도 있다.

[/list]

 

Text

사용자는 텍스트 뷰(UITextView)나 텍스트 필드(UITextField)를 통해 iOS 어플리케이션에서 텍스트를 입력할 수 있다. 이 클래스들은 사용자가 텍스트 관련 객체를 터치할 때 제공되는 가상 키보드의 모양과 동작을 지정하기 위해 UITextInputTraits 프로토콜을 따른다. 텍스트와 관련된 하위 클래스들도 반드시 이 프로토콜을 따라야 한다. 어플리케이션은 NSString 클래스의 카테고리인 UIStringDrawing에 정의되어 있는 메소드를 통해 텍스트를 그릴 수 있다. 그리고 UIFont 클래스를 사용해서 텍스트에서 사용할 폰트를 지정할 수도 있다.

텍스트 배치와 폰트 관리를 직접 수행하는 어플리케이션은 UITextInput 프로토콜을 적용하고 연관된 클래스와 프로토콜들을 사용하여 iOS의 텍스트 입력 시스템과 통신할 수 있다.

 

Comparing AppKit and UIKit Classes

AppKit과 UIKit은 각각 OS X와 iOS 플랫폼을 위해 설계된 코코아 어플리케이션 프레임워크이다. 이들 사이의 유사성으로 인해 각 프레임워크에 있는 대다수의 클래스들이 비슷한 이름을 가지는 것은 놀랄만한 사실이 아니다. 대부분 “NS” 접두어와 “UI” 접두어를 가지는 것이 유일한 차이점이다. 이렇게 이름이 유사한 클래스들은 대부분 비슷한 역할을 수행하지만, 차이점도 존재한다. 이러한 차이점은 범위(또는 한계), 상속, 설계로 인한 문제일 수 있다. 일반적으로 UIKit 클래스들은 AppKit에 있는 해당 클래스보다 적은 수의 메소드를 가진다.

표 1-1은 각 프레임워크에 있는 주요 클래스들의 차이점에 대해 설명한다.

Table 1-1  Major classes of the AppKit and UIKit frameworks
Classes Comparison
NSApplication
UIApplication
이 클래스들의 기본적인 역할은 매우 유사하다. 이들은 어플리케이션의 디스플리에 환경과 이벤트 루프, 이벤트 전달을 설정하고 특정 어플리케이션 이벤트 발생시 델리게이트로 통지해주는 싱글톤 객체를 제공한다. 하지만, NSApplication 클래스는 어플리케이션의 정지, 재활성, 숨기기와 같이 iOS 어플리케이션에서는 사용할 수 없는 기능들을 수행한다.
NSResponder
UIResponder
이 클래스들 역시 거의 유사한 역할을 가진다. 이들은 이벤트에 응답하고 응답체인을 관리하기 위한 인터페이스를 정의하고 있는 추상 클래스이다. 주요한 차이점은 NSResponder의 경우 마우스와 키보드를 위한 이벤트 처리 메소드를 정의하고 있고, UIResponder는 멀티 터치 이벤트 방식을 위한 메소드를 정의하고 있다는 것이다.
NSWindow
UIWindow
클래스 계층구조에서 UIWindow 클래스는 AppKit의 NSWindow가 차지하고 있는 위치와 차이점을 가진다. UIWindow는 UIView의 하위 클래스이고, 반면에 NSWindow 클래스는 NSResponder를 직접적으로 상속한다. UIWindow는 NSWindow에 비해 훨씬 제한된 역할을 가진다. 또한, 뷰 표시 영역, 이벤트 전달, 윈도우와 뷰 좌표 변환과 같은 기능들을 제공한다.
NSView
UIView
이 클래스들은 사용목적과 기본적인 메소드들이 매우 유사하다. 이들은 뷰의 이동과 크기변경, 계층구조 관리, 내용 그리기, 좌표 변환 등을 사용할 수 있도록 해준다. 하지만 UIView는 기본적으로 에니메이션 기능을 포함한다.
NSControl
UIControl
두 클래스 모두 객체를 조작할 때 대상 객체로 액션 메시지를 보낼 수 있는 매커니즘을 정의하고 있다. 하지만 이벤트 처리 방식의 차이로 인해 이 클래스들이 타겟-액션 매커니즘을 구성하는 방식에는 큰 차이가 존재한다.
NSViewController
UIViewController
이 클래스들의 역할은 이름에서도 알 수 있듯이 뷰를 관리하는 것이다. 이들이 이런 작업을 수행하는 방식은 서로 다르다. NSViewController 객체에서 제공되는 관리는 OS X에서만 지원되는 기술인 바인딩에 의존적이다. UIViewController 객체는 iOS 어플리케이션에 모달 인터페이스와 네비게이션 인터페이스를 관리하는데 사용된다.
NSTableView
UITableView
NSTableView는 NSControl에서 상속되지만 UITableView는 그렇지 않다. 더욱 중요한 것은 NSTableView 객체는 다중 컬럼을 지원한다. 반면 UITableView객체는 한번에 하나의 컬럼만을 표시하기 때문에 테이블 형태의 데이터를 표시하기 보다는 주로 목록을 표시하는 기능을 한다.

부차적인 클래스들 사이의 차이점도 발견할 수 있다. 예를 들어, UIKit에는 편집 가능한 텍스트 필드를 위한 UITextField와 레이블로 사용되는 편집 불가능한 필드인 UILabel 클래스가 존재한다. NSTextField 클래스를 사용하는 경우에는 텍스트 필드의 속성값을 통해 두가지 형태의 텍스트 필드를 손쉽게 만들 수 있다. 이와 마찬가지로 NSProgressIndicator 클래스는 UIProgressIndicator, UIProgressBar 클래스에 해당되는 스타일의 객체를 생성할 수 있다.

 

Core Data

Core Data는 다양한 파일 형식의 영구 저장소를 지원하고 객체 그래프 관리를 위한 인프라를 제공하는 코코아 프레임워크이다. 객체 그래프 관리에는 실행취소(undo), 다시 실행(redo), 유효성 검증(Validation), 객체 사이의 관계에 대한 유효성 보장과 같이 기능이 포함된다. 객체 영속화(Object persistence)는 코어 데이터가 모델 객체를 영구 저장소로 저장하고, 필요할 때 이 객체들을 다시 가져오는 작업을 의미한다. 코어 데이터 어플리케이션의 영구 저장소는 XML 파일에서부터 SQL 데이터베이스까지 다양하다. 코어 데이터는 관계 데이터베이스에 대한 프론트 엔드 역할(정보의 입력과 처리)을 수행하는 어플리케이션에 적합하지만, 어떠한 코코아 어플리케이션에서도 코어 데이터의 이점을 활용할 수 있다.

코어 데이터의 중심적인 개념(혹은 직관적 대상)은 managed object이다. managed object는 단순히 코어 데이터에 의해 관리되는 모델 객체이지만, 반드시 NSManagedObject 클래스 또는 이 클래스를 상속하는 클래스의 인스턴스여야 한다. 코어 데이터 어플리케이션의 managed object를 기술할 때는 managed object model이라고 하는 스키마를 사용한다. (Xcode는 이러한 스키마를 생성할 수 있도록 도와주는 데이터 모델링 도구를 포함하고 있다.) managed object model은 어플리케이션의 managed object에 대한 명세(description)를 담고 있으며, 이 명세를 Entity라고 부르기도 한다. 각 명세는 Entity의 속성, 다른 Entity와의 관계, 그리고 Entity의 이름, 연관된 클래스와 같은 메타데이터를 지정한다.

managed object context라고 하는 객체는 실행중인 코어 데이터 어플리케이션에서 managed object의 그래프를 관리한다. 그래프에 있는 모든 managed object들은 반드시 managed object context에 등록되어야 한다. 컨텍스트는 어플리케이션이 그래프에 객체를 추가하거나 삭제할 수 있도록 해준다. 또한, 이러한 객체에 대한 변경사항을 추적하므로 실행취소(undo), 다시 실행(redo)에 대한 지원을 제공할 수 있다. managed object context는 요청과 일치하는 객체들을 자동으로 자신에게 등록한 다음 저장소에서 리턴해준다.

또한 managed object context는 persistence stack이라고 하는 기본적인 코어 데이터 객체에 대한 게이트웨이 역할을 수행하기도 한다. persistence stack은 어플리케이션과 외부 데이터 저장소에 있는 객체들을 연결한다. 이 스택은 영구 저장소(persistent store)와 영구 저장소 코디네이터(persistent store coordinator)라고 하는 두개의 서로 다른 객체로 구성되어 있다. 영구 저장소는 스택의 아래쪽에 위치하며 외부 저장소에 있는 데이터와 managed object context에 있는 해당 객체 사이를 맵핑한다. 그러나 managed object context와 직접적으로 상호작용하지는 않는다. 영구 저장소 위쪽에는 영구 저장소 코디네이터가 위치한다. 이것은 자신의 아래쪽에 위치하고 있는 다수의 영구 저장소들이 하나 이상의 managed object context에서 단일 저장소로 보일 수 있도록 해주는 파사드(facade)를 제공한다. 그림 1-10은 코어 데이터 아키텍처에 존재하는 객체들 사이의 관계를 보여준다.

Figure 1-10  Examples of managed object contexts and the persistence stack

Figure 1-10 Examples of managed object contexts and the persistence stack

코어 데이터는 NSPersistentDocument 클래스를 포함하고 있다. 이 클래스는 NSDocument의 하위 클래스로 코어 데이터와 문서 아키텍처를 통합하는데 도움을 준다. 영구 문서 객체(persistent-document object)는 자신만의 persistence stack과 managed object context를 만들고 문서와 외부 데이터 저장소를 연결한다. NSPersistentDocument 객체는 문서 데이터 읽기와 쓰기에 사용되는 NSDocument 메소드에 대한 기본 구현을 제공한다.

 

Other Frameworks with a Cocoa API

Apple은 표준 설치의 한 부분으로 두 플랫폼의 주요한 프레임워크 뿐만 아니라 코코아 프로그래밍 인터페이스를 제공하는 다양한 프레임워크를 설치한다. 이러한 부가적인 프레임워크들을 통해 기본적이지는 않지만 어플리케이션에서 필요로 하는 기능들을 구현할 수 있다. 몇가지 주목할만한 프레임워크는 다음과 같다.

[list style=”star”]

  • Sync Services—(OS X 전용) 동기화 서비스를 통해 주소록, 달력, 즐겨찾기 뿐만 아니라 어플리케이션의 데이터 등을 동기화 할 수 있다. 또한 이미 존재하는 스키마를 확장할 수도 있다. 자세한 정보는 Sync Services Programming Guide에서 제공한다.
  • Address Book—이 프레임워크는 연락처와 또 다른 사용자 정보에 대한 centralized database(중앙 집중식 데이터베이스)를 구현한다. 주소록을 사용하는 어플리케이션은 Apple에서 제공하는 Mail이나 iChat과 같은 다른 어플리케이션과 연락처 정보를 공유할 수 있다. 자세한 정보는 Address Book Programming Guide for Mac에서 제공한다.[note color=”#fffbb8″]iOS Note: 이 프레임워크는 OS X와 iOS에 따라 다른 버전이 존재한다. 그리고 iOS에 있는 Address Book 프레임워크는 ANSI C 방식(절차적)의 프로그래밍 인터페이스만을 제공한다.[/note]
  • Preference Panes—(OS X 전용) 이 프레임워크를 통해 어플리케이션이 동적으로 로딩하는 플러그인을 만들 수 있다. 이 플러그인은 어플리케이션 자체의 설정이나 시스템 전역 설정을 기록하는 사용자 인터페이스를 얻는데 사용된다. 자세한 정보는 Preference Pane Programming Guide에서 제공한다.
  • Screen Saver—(OS X 전용) Screen Saver 프레임워크는 화면 보호기와 관련된 화면 효과 모듈을 생성하는데 도움을 준다. 자세한 정보는 Screen Saver Framework Reference에서 제공한다.
  • WebKit—(iOS에서는 공개되어 있지 않음) WebKit 프레임워크는 창에서 웹 컨텐츠를 표시하기 위해 사용되는 주요 클래스들을 제공하며 기본적으로 링크 이동과 같은 기능들을 구현하고 있다. 자세한 정보는 WebKit Objective-C Programming Guide에서 제공한다.
  • iAd—(iOS 전용) 이 프레임워크는 어플리케이션이 사용자에게 광고를 보여주고 수입을 얻을 수 있도록 해준다.
  • Map Kit—(iOS 전용) 이 프레임워크는 어플리케이션이 자신의 창과 뷰에 지도를 포함시킬수 있도록 해준다. 또한 map annotation(지도 주석)과 overlay(부가적인 정보를 제공할 수 있는 투명한 화면), reverse-geocoding lookup(좌표 지명 변환 검색)을 지원한다.
  • Event Kit—(iOS 전용) 어플리케이션은 Event Kit 프레임워크를 통해 사용자의 달력 데이터베이스에 있는 이벤트 정보에 접근할 수 있으며, 사용자들이 새로운 이벤트를 생성하거나 편집할 수 있도록 해준다. 이 프레임워크는 효율적인 이벤트 레코드 가져오기, 이벤트 변경 통지, 적합한 달력 데이터베이스와의 자동 동기화 기능도 지원한다.
  • Core Motion—(iOS 전용) Core Motion은 디바이스의 가속도계와 자이로스코프로부터 전달되는 저수준의 데이터를 가공하여 어플리케이션이 처리할 수 있도록 제공한다.
  • Core Location—(iOS 전용) Core Location은 어플리케이션이 디바이스의 현지 위치나 방향을 측정할 수 있도록 해준다. 어플리케이션은 이 프레임워크를 통해 지리적 영역을 정의하고 사용자가 이 영역의 경계를 지나가는 시점을 감시할 수 있다.
  • Media Player—(iOS 전용) 이 프레임워크는 어플리케이션이 영화, 음악, 오디오 팟캐스, 음석 책 파일을 재생할 수 있도록 해준다. 또한 어플리케이션이 iPod 라이브러리에 접근할 수 있도록 해준다.

[/list]

 

A Bit of History

수년 전 코코아는 NeXTSTEP으로 알려져 있었다. NeXT 컴퓨터는 NeXTSTEP 1.0 버전을 통해 개발되어 1989년 9월에 출시되었고, 얼마 지나지 않아 2.0버전과 3.0버전이 출시되었다. 초기의 NeXTSTEP은 개발 환경 그 이상이었다. 이 용어는 windowing(여러 개의 파일을 보기 위해 화면의 일부를 창 모양으로 분할하는 방식), Display PostScript에 기반한 이미지 처리 시스템, Mach 커널, 디바이스 드라이버 등을 포함한 전체 운영체체를 나타내는 것이었다.

그 당시에는 Foundation 프레임워크가 존재하지 않았다. 사실은 프레임워크라는 것 자체가 존재하지 않았다. 대신 kit이라고 하는 소프트웨어 라이브러리(동적으로 공유됨) 중 가장 유명한 것들이 Application Kit이 되었다. 현재 Foundation이 차지하고 있는 대부분의 역할은 함수, 구조체, 상수와 같은 부류를 통해 수행되었다. Application Kit은 오늘날과 아주 유사한 클래스의 모음을 가지고 있었다. 그림 1-11은 1988년 출시된 NeXTSTEP 0.9의 클래스 계층구조를 보여준다.

Figure 1-11  Application Kit class hierarchy in 1988

Figure 1-11 Application Kit class hierarchy in 1988

초기 NeXTSTEP에는 Application Kit 뿐만 아니라 Sound Kit과 Music Kit도 포함되어 있었다. 이들은 오디오의 Display Postscript 계층에 대한 고수준의 접근을 제공하는 다양한 Objective-C 클래스들을 포함하고 있는 라이브러리이다.

1993년 초반 NeXTSTEP 3.1은 인텔, Sparc, 휴렛팩커드 컴퓨터로 이식되었다. NeXTSTEP 3.3은 Foundation의 예비 버전을 포함하고 있었기 때문에 중요한 버전으로 평가되고 있다. 이 시기에 OpenStep 계획도 구체적인 형태를 갖추게 되었다. OpenStep은 Application Kit, Display PostScript와 같은 고수준의 NeXTSTEP을 솔라리스로 이식하기 위한 Sun과 NeXT의 공동작업이었다. 이 이름에서 “Open”은 이 회사들이 공동으로 발표할 공개 API 사양을 나타내는 것이었다. 1994년 9월에 발표된 공식 OpenStep API는 처음으로 Foundation과 Application Kit으로 분리하고 “NS”를 접두어로 사용하였다. Application Kit은 머지않아 AppKit이 되었다.

NeXT는 1996년 6월까지 인텔, Sparc, 휴렛팩커드 컴퓨터에서 실행될 수 있는 OpenStep 4.0 버전과 윈도우즈 시스템에서 실행될 수 있는 OpenStep 런타임을 출시하였다. 또한 Sun은 OpenStep의 솔라리스 이식을 완료하고 그들의 Network Object Computing Environment의 한 부분으로 출시하였다. 하지만 OpenStep은 Sun의 전체적인 전략에서 중요한 부분을 차지하지는 못했다.

1997년 Apple이 NeXT Software를 인수했을 때, OpenStep은 Yellow Box가 되었고 OS X 서버와 윈도우즈에 포함되었다. 그 후 OS X 전략의 진화와 함께 최종적으로 코코아라는 이름을 가지게 되었다.

 

(이 글은 Cocoa Fundamentals Guide 중 What is Cocoa?를 번역한 글입니다. 개인적인 학습목적으로 번역한 것이기 때문에 잘못 번역된 부분이나 어색한 문장이 많이 있습니다.^^;;)

Filed under: Apple Developer Document, iOS

  1. 수고하셨습니다, 잘읽고 갑니다, 개인적으로 Cocoa Touch에도 관심이 있지만, Cocoa에 더 관심을 가지고 있는 일인으로서, 감사한 마음을 남깁니다.
    http://about.me/klarheit