Cocoa

**Cocoa** 是蘋果公司為 macOS 所建立的原生物件導向的應用程式介面，是 Mac OS X 上五大 API 之一（其它四個是 Carbon、POSIX、X11 和 Java）。

Cocoa 應用程式一般在蘋果公司的開發工具 Xcode（前身為 Project Builder）和 Interface Builder 上用 Objective-C 寫成。不過，通過 Java bridge、PasCocoa、PyObjC、CamelBones 以及 RubyCocoa 等橋接技術，Java、Clozure CL、LispWorks、Object Pascal、Python、Perl、Ruby 等其它工具或者語言也可以用來開發 Cocoa 應用。也有一些其它語言的 Cocoa 實現無須橋接，比如蘋果公司開發的 MacRuby 和類似 Lisp 的 Nu 語言。不使用 Xcode 和 Interface Builder，僅僅通過文字編輯器、GCC 和 GNU make 工具也可以用 Objective-C 語言開發 Cocoa 應用。

對終端使用者來說，使用 Cocoa 編程環境開發的應用程式即為 **Cocoa 應用程式**。這類應用有獨特的外觀，因為 Cocoa 編程環境讓程式在多方面自動遵循蘋果公司的人機介面守則。

## Cocoa 歷史

Cocoa 是從 1980 年代由 NeXT 開發的編程環境 NeXTSTEP 和 OPENSTEP 演變而來，這點可由其類別之名皆以 NS 前綴（代表 NeXTSTEP）看出端倪。蘋果電腦公司在 1996 年 12 月收購了 NeXT。開發 NeXTSTEP 和 OPENSTEP 的大量工作都轉化到了 Mac OS X 中，最顯而易見的部分當屬 Cocoa。但差異也存在。例如，NeXTSTEP 和 OPENSTEP 使用 Display PostScript 實現文字和圖形的螢幕顯示，而 Cocoa 依賴蘋果的 Quartz（基於 PDF 的繪圖模型）。

Cocoa 這個名詞曾經被用來稱呼一款幫助兒童建立多媒體工程的應用程式。隨後該應用停產。該名稱被用作現在的用途。

## 記憶體管理

Cocoa 環境的一個特點是它可以管理動態分配的記憶體。Cocoa 中絕大部分類的基礎類別都是 NSObject，它實現了參照計數的記憶體管理模型。從 NSObject 繼承的類可以回應 `retain` 和 `release` 訊息，以增減其參照計數；也可以通過傳送 `retainCount` 訊息來取得其參照計數。一個以 `alloc`，`copy` 或 Objective-C 2.0 中增加的 `new` 所建立的物件的參照計數為 1；向物件傳送 `retain` 訊息會將計數加 1，而傳送 `release` 訊息則會將計數減 1。若物件的參照計數減少到了 0，則它會被銷毀。`dealloc` 訊息類似於 C++ 中的解構函式，在物件被銷毀之前可能會被呼叫，但系統不保證會傳送該訊息。這種參照計數的模型與微軟的 COM 中的 IUnknown 介面特性十分相似，它提供了 `AddRef` 和 `Release` 介面，與 `retain` 和 `release` 對應。

從 Objective-C 2.0 開始，Objective-C 執行時實現了可選的垃圾收集器。若垃圾收集的特性被啟用，則執行時會將參照計數相關的操作，例如「retain」和「release」，變為無操作。iOS 上的 Objective-C 2.0 實現中不包含垃圾收集器。垃圾收集器執行在一個低優先級的後台執行緒中，並可以在使用者動作時暫停，從而保持良好的使用者體驗。

## 主要框架

Cocoa 包含三個主要的 Objective-C 物件庫，稱為「框架」。框架的功能類似於動態庫，即可以在執行時動態的載入應用程式的位址空間，但框架作為一個捆綁而非獨立檔案，其中除了可執行代碼外，也包含了資源，標頭檔和文件。

* 「Foundation 工具包」，或簡稱為「Foundation」，首先出現在 OpenStep 中。在 Mac OS X 中，它是基於 Core Foundation 的。作為通用的物件導向的函式庫，Foundation 提供了字串，數值的管理，容器及其列舉，分散式計算，事件迴圈，以及一些其它的與圖形化使用者介面沒有直接關係的功能。其中用於類和常數的「NS」字首來自於 Cocoa 的來源，NeXTSTEP。它可以在 Mac OS X 和 iOS 中使用。
* 「應用程式工具包」，或稱 AppKit（**App**lication **Kit**）是直接衍生自 NeXTSTEP 的 AppKit 的。它包含了程式與圖形化使用者介面互動所需的代碼。它是基於 Foundation 建立的，也使用「NS」字首。它只能在 Mac OS X 中使用。
* 「使用者介面工具包」，或稱 UIKit（**U**ser **I**nterface **Kit**），是用於 iOS 的圖形化使用者介面工具包。與 AppKit 不同，它使用「UI」的字首。

Cocoa 構架的一個關鍵部分是其多樣的視圖模型。總體而言，它是基於由 Quartz 提供的 PDF 繪製模型的，該特性允許使用 PostScript 繪製自訂圖形內容，同時也自動的支援了印表機以及類似裝置。由於 Cocoa 框架管理了全部的繪圖操作，例如裁剪，捲動，縮放等，程式設計師可以不再重複實現基礎的功能，而可以集中於提供程式的關鍵功能上。

## 模型 - 視圖 - 控制器

全錄帕羅奧多研究中心的 Smalltalk 開發小組最終發明了一種可以簡化開發過程，提高代碼重用率的設計哲學，即「模型 - 視圖 - 控制器」模式（MVC）。這種模式將應用程式分為三個可以互動的物件集，即模型，視圖和控制器。其中，模型類代表原始資料，例如文件、設定、檔案、記憶體中的物件等，視圖是模型中資料的視覺化表現，而控制器類則包含了將模型和其對應視圖連接起來的邏輯，並保持前二者的狀態同步。

Cocoa 的設計遵循了嚴格的 MVC 原則。在 OpenStep 下，絕大多數的類要麼是高層的視圖類（AppKit），或者是相對底層的模型類（Foundation）。與類似的 MVC 系統相比，OpenStep 沒有強的模型層，例如它不包含表示「文件」的儲存類。在向 Cocoa 遷移的過程中，模型層被大大擴充了，引入了一系列的類，它們提供了一些桌面程式所需的常用功能。

在 Mac OS X 10.3 中，蘋果引入了 NSController 系列類以提供預定義的控制器層。這些類是 Cocoa 繫結系統的一部分，該系統也允許使用類似鍵 - 值 - 觀測器和鍵 - 值 - 繫結協定來對其進行擴充。其中，「繫結」的概念表明兩個物件（通常是視圖和控制器）之間的關係。繫結使得開發者可以集中於定義這種關係，而不是編寫大量的「膠水代碼」來實現這些關係。

在 Mac OS X 10.4 中，蘋果引入了 Core Data 框架，進一步擴充了這種概念。Core Data 標準化了對更改的追蹤和模型層的儲存行為。因此，該框架大大簡化了改變應用程式資料，復原更改，在磁碟中儲存和讀取資料的過程。

通過提供對 MVC 模型中全部 3 層的框架支援，蘋果的目的在於減少程式設計師所需編寫的「膠水代碼」量，以解放這些資源而用於程式的真正特性。

## 動態繫結

在多數物件導向的程式語言中，呼叫方法是由直接呼叫記憶體中一段固定的代碼實現的。由於這種方法需要預定義的處理命令的類，因而限制了程式的設計，通常採用責任鏈模式作為其設計模式。雖然 Cocoa 在多數地方仍然採用這種方式，但通過 Objective-C 的動態繫結特性增加了更多設計的自由性。

在 Objective-C 中，訊息由 **selector** 所代表，其為描述需要呼叫的方法的一個字串。在傳送訊息時，該 selector 被送入 Objective-C 執行時中，在可用方法列表中尋找對應的方法，然後呼叫該方法的實際**實現**。由於 selector 只是文字資料，因此它可以儲存在檔案中，通過網路或在行程間傳輸，或以其它方式進行操作。方法的實現是在執行時尋找的，而非編譯時。這樣的做法會造成一些效能損失，但動態繫結允許相同的 selector 代表不同的實現。

利用這些特性，Cocoa 提供了一種通用的資料管理技術，稱為**鍵 - 值編碼**(KVC)。這種技術允許物件的資料或屬性可以在執行時通過其鍵名進行尋找，其中，屬性的名稱即為其值的鍵名。在靜態語言中，這樣的做法是不可能的。KVC 大大的增加了設計的自由度：通過 KVC，無需知道物件的類型即可存取其屬性或資料。另外，利用**鍵 - 值 - 觀測器**（KVO）技術和 NSUndoManager 類，可以提供自動的復原 / 重做支援。

## Rich objects

Cocoa 中最有用的特性是系統提供的強大的「基礎物件」，例如 Foundation 中的 `NSString` 和 `NSAttributedString` 類，提供了 Unicode 字串的支援；而 AppKit 中的 `NSText` 系統則允許程式設計師在 GUI 中放置字串物件。

`NSText` 及其相關類是用於顯示和編輯字串的。這些物件允許程式實現簡單的單行文字方塊，也可以實現完整的多頁，多欄文字顯示方案
，方案同時可以提供支援完整的專業排版特性，例如壓縮字元，合字，環繞形狀的文字，旋轉，完整的 Unicode 支援和反鋸齒字形彩現。段落格式可以自動控制或由使用者自訂；可以使用內建的「ruler」物件附加到任何文字視圖上。這些類也有自動拼寫檢查特性，該特性使用一個由所有程式共享的字典。另外，也允許無限制數量的復原 / 重做操作。只使用內建的特性，任何人都可以只用不到 10 行代碼寫出一個具備上述特性的文字編輯器，而若使用 Cocoa 繫結，甚至可以不用寫一行代碼。

若需要對已有特性進行擴充，Objective-C 中的類別特性使得這項操作變得相當容易。通過類別可以直接對已有類進行功能添加，而無需對其進行更改或獲得其原始碼。一般而言，這樣的目的需要通過繼承原有的類並修改原有的代碼，將原有的類以新的子類代替來完成。

## 實現

Cocoa 本身由 Objective-C 語言寫成，因此 Objective-C 是開發 Cocoa 應用的首選語言。雖然也提供 Java 到 Cocoa 的繫結，但是在開發者中並未得到廣泛採用。而且，由於使用橋接機制，Java 的繫結並不能全面利用 Cocoa 的所有功能。2005 年，蘋果公司宣布 Java 的 Cocoa 繫結在 Mac OS X 10.4 和之後版本中屬被廢棄的技術。換句話說，Cocoa API 中可能會逐漸出現不支援 Java 的功能。

作為 Xcode 一部分的 AppleScript Studio 工具允許使用者和開發者用 AppleScript 編寫一些簡單的 Cocoa 應用。第三方實現的繫結有 Clozure CL、LispWorks、PyObjC（Python）、RubyCocoa（Ruby）、CamelBones（Perl）、Cocoa#、Monobjc（C#）和 NObjective（C#）。Nu 語言直接使用 Objective-C 的物件模型，所以無須繫結就可以呼叫 Cocoa API。

也有開源專案把 Cocoa 的大部分在其它作業系統上實現（包括 Windows），從而使開發跨平台的 Cocoa 應用成為可能。比如 GNUstep 和 Cocotron。

## 參考文獻

## 外部連結

* Apple 的 Cocoa 文件
* iDevApps - Cocoa 編程論壇
* CocoaDev
* Cocoa Dev Central（頁面存檔備份，存於網際網路檔案館）