Objective-C_2.0

**Objective-C** 是一種通用、進階、物件導向的程式語言。它擴充了標準的 ANSI C 程式語言，將 Smalltalk 式的訊息傳遞機制加入到 ANSI C 中。目前主要支援的編譯器有 GCC 和 Clang（採用 LLVM 作為後端）。

Objective-C 的商標權屬於蘋果公司，蘋果公司也是這個程式語言的主要開發者。蘋果在開發 NeXTSTEP 作業系統時使用了 Objective-C，之後被 macOS,iPadOS,watchOS 和 iOS 繼承下來。現在 Objective-C 與 Swift 是 OS X 和 iOS 作業系統、及與其相關的 API、Cocoa 和 Cocoa Touch 的主要程式語言。

## 歷史

Objective-C 主要由 Stepstone 公司的布萊德・考克斯（Brad Cox）和 湯姆・洛夫（Tom Love） 在 1980 年代發明。

1981 年 Brad Cox 和 Tom Love 還在 ITT 公司技術中心任職時，接觸到了 SmallTalk 語言。Cox 當時對軟體設計和開發問題非常感興趣，他很快地意識到 SmallTalk 語言 在系統工程構建中具有無法估量的價值，但同時他和 Tom Love 也明白，目前 ITT 公司的電子通信工程相關技術中，C 語言被放在很重要的位置。

於是 Cox 撰寫了一個 C 語言的預處理器，打算使 C 語言具備些許 Smalltalk 的本領。Cox 很快地實現了一個可用的 C 語言擴展，此即為 Objective-C 語言的前身。到了 1983 年，Cox 與 Love 合夥成立了 Productivity Products International（PPI）公司，將 Objective-C 及其相關函式庫商品化販售，並在之後將公司改名為 StepStone。1986 年，Cox 出版了一本關於 Objective-C 的重要著作《Object-Oriented Programming, An Evolutionary Approach》，書內詳述了 Objective-C 的種種設計理念。

1988 年，斯蒂夫・賈伯斯（Steve Jobs）離開蘋果公司後成立了 NeXT Computer 公司，NeXT 公司買下 Objective-C 語言的授權，並擴展了著名的開源編譯器 GCC 使之支援 Objective-C 的編譯，基於 Objective-C 開發了 AppKit 與 Foundation Kit 等函式庫，作為 NeXTSTEP 的的使用者介面與開發環境的基礎。雖然 NeXT 工作站後來在市場上失敗了，但 NeXT 上的軟體工具卻在業界中被廣泛讚揚。這促使 NeXT 公司放棄硬體業務，轉型為銷售 NeXTStep（以及 OpenStep）平台為主的軟體公司。

1992 年，自由軟體基金會的 GNU 開發環境增加了對 Objective-C 的支援。1994 年，NeXT Computer 公司和 Sun Microsystem 聯合發布了一個針對 NEXTSTEP 系統的標準典範，名為 OPENSTEP。OPENSTEP 在自由軟體基金會的實現名稱為 GNUstep。1996 年 12 月 20 日，蘋果公司宣布收購 NeXT Software 公司，NEXTSTEP/OPENSTEP 環境成為蘋果作業系統下一個主要發行版本 OS X 的基礎。這個開發環境的版本被蘋果公司稱為 Cocoa。

2005 年，蘋果電腦雇用了克里斯・拉特納及 LLVM 開發團隊，clang 及 LLVM 成為蘋果公司在 GCC 之外的新編譯器選擇，在 Xcode 4.0 之後均採用 LLVM 作為默認的編譯器。最新的 Modern Objective-C 特性也都率先在 Clang 上實現。

## 語法

Objective-C 是 C 語言的嚴格超集－－任何 C 語言程式不經修改就可以直接通過 Objective-C 編譯器，在 Objective-C 中使用 C 語言代碼也是完全合法的。Objective-C 被描述為_蓋在 C 語言上的薄薄一層_，因為 Objective-C 的原意就是在 C 語言主體上加入物件導向的特性。Objective-C 的物件導向語法源於 Smalltalk 訊息傳遞風格。所有其他非物件導向的語法，包括變數型別，預處理器（preprocessing），流程控制，函式聲明與呼叫皆與 C 語言完全一致。但有些 C 語言語法合法代碼在 objective-c 中表達的意思不一定相同，比如某些布林表達式，在 C 語言中返回值為 true，但在 Objective-C 若與 true 直接相比較，函式將會出錯，因為在 Objective-C 中 true 的值只表示為 1.

### Hello World

這里示範了一個基礎的 Hello World 程式。基於 Xcode 4.3.1:

### 訊息傳遞

Objective-C 最大的特色是承自 Smalltalk 的訊息傳遞模型（message passing），此機制與今日 C++ 式之主流風格差異甚大。Objective-C 裡，與其說物件互相**呼叫方法**，不如說物件之間**互相傳遞訊息**更為精確。此二種風格的主要差異在於_呼叫方法 / 訊息傳遞_這個動作。C++ 裡類別與方法的關係嚴格清楚，一個方法必定屬於一個類別，而且在編譯時（compile time）就已經緊密綁定，不可能呼叫一個不存在類別裡的方法。但在 Objective-C，類別與訊息的關係比較鬆散，呼叫方法視為對物件_發送訊息_，所有方法都被視為_對訊息的回應_。所有訊息處理直到執行時（runtime）才會動態決定，並交由類別自行決定如何處理收到的訊息。也就是說，一個類別不保證一定會回應收到的訊息，如果類別收到了一個無法處理的訊息，程式只會拋出異常，不會出錯或崩潰。

C++ 裡，送一個訊息給物件（或者說呼叫一個方法）的語法如下：

Objective-C 則寫成：

此二者並不僅僅是語法上的差異，還有基本行為上的不同。

這裡以一個汽車類（car class）的簡單例子來解釋 Objective-C 的訊息傳遞特性：

典型的 C++ 意義解讀是「呼叫 car 類別的 fly 方法」。若 car 類別裡頭沒有定義 fly 方法，那編譯肯定不會通過。但是 Objective-C 裡，我們應當解讀為「發送出一個 fly 的訊息給 car 物件」，fly 是_訊息_，而 car 是訊息的_接收者_。car 收到訊息後會決定如何回應這個訊息，若 car 類別內定義有 fly 方法就執行方法內之代碼，若 car 內不存在 fly 方法，則程式依舊可以通過編譯，執行期則拋出異常。

此二種風格各有優劣。C++ 強制要求所有的方法都必須有對應的動作，且編譯期綁定使得函式呼叫非常快速。缺點是僅能藉由 virtual 關鍵字提供有限的動態綁定能力。Objective-C 天生即具備鴨子型別之動態綁定能力，因為執行期才處理訊息，允許傳送未知訊息給物件。可以送訊息給整個物件集合而不需要一一檢查每個物件的型態，也具備訊息轉送機制。同時空物件 nil 接受訊息後默認為不做事，所以送訊息給 nil 也不用擔心程式崩潰。

### 類的定義與實現

Objective-C 中強制要求將類的介面（interface）與實現（implementation）分為兩個部分。

類的定義檔案遵循 C 語言之慣例以.h 為字尾，實現檔案以.m 為字尾。

#### 介面

定義部分，清楚定義了類的名稱、成員變數和方法。
以關鍵字 @interface 作為開始，@end 作為結束。

方法前面的 +/- 號代表函式的類型：加號（+）代表類別方法（class method），不需要實例就可以呼叫，與 C++ 的靜態函式（static member function）相似。減號（-）即是一般的實例方法（instance method）。

這裡提供了一份意義相近的 C++ 語法對照，如下：

Objective-C 定義一個新的方法時，名稱內的冒號（:）代表參數傳遞，不同於 C 語言以數學函式的括號來傳遞參數。Objective-C 方法使得參數可以夾雜於名稱中間，不必全部附綴於方法名稱的尾端，可以提高程式可讀性。設定顏色 RGB 值的方法為例：

這個方法的簽名是 setColorToRed:Green:Blue:。每個冒號後面都帶著一個 float 類別的參數，分別代表紅，綠，藍三色。

#### 實現

實現區段則包含了公開方法的實現，以及定義私有（private）變數及方法。
以關鍵字 @implementation 作為區段起頭，@end 結尾。

值得一提的是不只 Interface 區段可定義實體變數，Implementation 區段也可以定義實體變數，兩者的差別在於存取權限的不同，Interface 區段內的實體變數默認權限為 protected，宣告於 implementation 區段的實體變數則默認為 private，故在 Implementation 區段定義私有成員更符合物件導向之封裝原則，因為如此類別之私有資訊就不需曝露於公開 interface（.h 檔案）中。

#### 建立物件

Objective-C 建立物件需通過 alloc 以及 init 兩個訊息。alloc 的作用是分配記憶體，init 則是初始化物件。
init 與 alloc 都是定義在 NSObject 里的方法，父物件收到這兩個資訊並做出正確回應後，新物件才建立完畢。以下為範例：

在 Objective-C 2.0 裡，若建立物件不需要參數，則可直接使用 new

僅僅是語法上的精簡，效果完全相同。

若要自己定義初始化的過程，可以重寫 init 方法，來添加額外的工作。（用途類似 C++ 的建構函式 constructor）

### 協定

協定是一組沒有實現的方法列表，任何的類均可採納協定並具體實現這組方法。

Objective-C 在 NeXT 時期曾經試圖引入多重繼承的概念，但由於協定的出現而沒有實現之。

協定類似於 Java 與 C# 語言中的「介面」。在 Objective-C 中，有兩種定義協定的方式：由編譯器保證的「正式協定」，以及為特定目的設定的「非正式協定」。

**非正式協定**為一個可以選擇性實現的一系列方法列表。非正式協定雖名為協定，但實際上是掛於 NSObject 上的未實現分類（Unimplemented Category）的一種稱謂，Objetive-C 語言機制上並沒有非正式協定這種東西，OSX 10.6 版本之後由於引入 @optional 關鍵字，使得正式協定已具備同樣的能力，所以非正式協定已經被廢棄不再使用。

**正式協定**類似於 Java 中的 "介面"，它是一系列方法的列表，任何類都可以聲明自身實現了某個協定。在 Objective-C 2.0 之前，一個類必須實現它聲明符合的協定中的所有方法，否則編譯器會報告錯誤，表明這個類沒有實現它聲明符合的協定中的全部方法。Objective-C 2.0 版本允許標記協定中某些方法為可選的（Optional），這樣編譯器就不會強制實現這些可選的方法。

協定經常應用於 Cocoa 中的委託及事件觸發。例如文字方塊類通常會包括一個委託（delegate）物件，該物件可以實現一個協定，該協定中可能包含一個實現文字輸入的自動完成方法。若這個委託物件實現了這個方法，那麼文字方塊類就會在適當的時候觸發自動完成事件，並呼叫這個方法用於自動完成功能。

Objective-C 中協定的概念與 Java 中介面的概念並不完全相同，即一個類可以在不聲明它符合某個協定的情況下，實現這個協定所包含的方法，也即實質上符合這個協定，而這種差別對外部代碼而言是不可見的。正式協定的聲明不提供實現，它只是簡單地表明符合該協定的類實現了該協定的方法，保證呼叫端可以安全調用方法。

語法

協定以關鍵字 @protocol 作為區段起始，@end 結束，中間為方法列表。

這是一個協定的例子，多執行緒編程中經常要確保一份共享資源同時只有一個執行緒可以使用，會在使用前給該資源掛上鎖
，以上即為一個表明有「鎖」的概念的協定，協定中有兩個方法，只有名稱但尚未實現。

下面的 SomeClass 宣稱他採納了 Locking 協定：

一旦 SomeClass 表明他採納了 Locking 協定，SomeClass 就有義務實現 Locking 協定中的兩個方法。

由於 SomeClass 已經確實遵從了 Locking 協定，故調用端可以安全的發送 lock 或 unlock 訊息給 SomeClass 實體變數，不需擔心他沒有辦法回應訊息。

外掛程式是另一個使用抽象定義的例子，可以在不關心外掛程式的實現的情況下定義其希望的行為。

### 動態型別

類似於 Smalltalk，Objective-C 具備動態型別：即訊息可以傳送給任何物件實體，無論該物件實體的公開介面中有沒有對應的方法。對比於 C++ 這種靜態類型的語言，編譯器會擋下對（void\*）指針調用方法的行為。但在 Objective-C 中，你可以對 id 發送任何訊息（id 很像 void\*，但是被嚴格限制只能使用在物件上），編譯器僅會發出「該物件可能無法回應訊息」的警告，程式可以通過編譯，而實際發生的事則取決於執行期該物件的真正形態，若該物件的確可以回應訊息，則依舊執行對應的方法。

一個物件收到訊息之後，他有三種處理訊息的可能手段，第一是回應該訊息並執行方法，若無法回應，則可以轉發訊息給其他物件，若以上兩者均無，就要處理無法回應而拋出的例外。只要進行三者之其一，該訊息就算完成任務而被丟棄。若對「nil」（空物件指標）傳送訊息，該訊息通常會被忽略，取決於編譯器選項可能會拋出例外。

雖然 Objective-C 具備動態類型的能力，但編譯期的靜態型別檢查依舊可以應用到變數上。以下三種聲明在執行時效力是完全相同的，但是三種聲明提供了一個比一個更明顯的類型資訊，附加的類型資訊讓編譯器在編譯時可以檢查變數類型，並對類型不符的變數提出警告。

下面三個方法，差異僅在於參數的形態：

id 形態表示參數「foo」可以是任何類別的實例。

id<aProtocol> 表示「foo」可以是任何類別的實例，但必須採納「aProtocol」協定。

該聲明表示「foo」必須是「NSNumber」的實例。

動態型別是一種強大的特性。在缺少泛型的靜態型別語言（如 Java 5 以前的版本）中實現容器類時，程式設計師需要寫一種針對通用類型物件的容器類，然後在通用類型和實際類型中不停的強制類型轉換。無論如何，類型轉換會破壞靜態類型，例如寫入一個「整數」而將其讀取為「字串」會產生執行時錯誤。這樣的問題被泛型解決，但容器類需要其內容物件的類型一致，而對於動態型別語言則完全沒有這方面的問題。

### 轉發

Objective-C 允許對一個物件傳送訊息，不管它是否能夠回應之。除了回應或丟棄訊息以外，物件也可以將訊息轉發到可以回應該訊息的物件。轉發可以用於簡化特定的設計模式，例如觀測器模式或代理模式。

Objective-C 執行時在 Object 中定義了一對方法：

* 轉發方法：

* 回應方法：

希望實現轉發的物件只需用新的方法覆蓋以上方法來定義其轉發行為。無需重寫回應方法 performv::，由於該方法只是單純的對回應物件傳送訊息並傳遞參數。其中，`SEL` 類型是 Objective-C 中訊息的類型。

#### 例子

這裡包括了一個示範轉發的基本概念的程式範例。

**_Forwarder.h_**

**_Forwarder.m_**

**_Recipient.h_**

**_Recipient.m_**

**_main.m_**

#### 註腳

利用 GCC 編譯時，編譯器報告：

```
$ gcc -x objective-c -Wno-import Forwarder.m Recipient.m main.m -lobjc
main.m: In function `main':
main.m:12: warning: `Forwarder' does not respond to `hello'
$
```

如前文所提到的，編譯器報告 Forwarder 類不回應 hello 訊息。在這種情況下，由於實現了轉發，可以忽略這個警告。
執行該程式產生如下輸出：

```
$ ./a.out
Recipient says hello!
```

### 類別 (Category)

在 Objective-C 的設計中，一個主要的考慮即為大型代碼框架的維護。結構化編程的經驗顯示，改進代碼的一種主要方法即為將其分解為更小的片段。Objective-C 借用並擴充了 Smalltalk 實現中的「分類」概念，用以幫助達到分解代碼的目的。

一個分類可以將方法的實現分解進一系列分離的檔案。程式設計師可以將一組相關的方法放進一個分類，使程式更具可讀性。舉例來講，可以在字串類中增加一個名為「拼寫檢查」的分類，並將拼寫檢查的相關代碼放進這個分類中。

進一步的，分類中的方法是在執行時被加入類中的，這一特性允許程式設計師向現存的類中增加方法，而無需持有原有的代碼，或是重新編譯原有的類。例如若系統提供的字串類的實現中不包含拼寫檢查的功能，可以增加這樣的功能而無需更改原有的字串類的代碼。

在執行時，分類中的方法與類原有的方法並無區別，其代碼可以存取包括私有類別成員變數在內的所有成員變數。

若分類聲明了與類中原有方法同名的函式，則分類中的方法會被呼叫。因此分類不僅可以增加類的方法，也可以代替原有的方法。這個特性可以用於修正原有代碼中的錯誤，更可以從根本上改變程式中原有類的行為。若兩個分類中的方法同名，則被呼叫的方法是不可預測的。

其它語言也嘗試了通過不同方法增加這一語言特性。TOM 在這方面走的更遠，不僅允許增加方法，更允許增加成員變數。也有其它語言使用面向聲明的解決方案，其中最值得注意的是 Self 語言。

C# 與 Visual Basic.NET 語言以擴充函式的與不完全類的方式實現了類似的功能。Ruby 與一些動態語言則以 "Monkey patch" 的名字稱呼這種技術。

#### 使用分類的例子

這個例子建立了 Integer 類，其本身只定義了 integer 屬性，然後增加了兩個分類 Arithmetic 與 Display 以擴充類的功能。雖然分類可以存取類的私有成員，但通常利用屬性的存取方法來存取是一種更好的做法，可以使得分類與原有類更加獨立。這是分類的一種典型應用 — 另外的應用是利用分類來替換原有類中的方法，雖然用分類而不是繼承來替換方法不被認為是一種好的做法。

**_Integer.h_**

**_Integer.m_**

**_Arithmetic.h_**

**_Arithmetic.m_**

**_Display.h_**

**_Display.m_**

**_main.m_**

#### 注釋

可以利用以下命令來編譯：

```
gcc -x objective-c main.m Integer.m Arithmetic.m Display.m -lobjc
```

在編譯時間，可以利用省略#import "Arithmetic.h" 與[num1 add:num2]命令，以及 Arithmetic.m 檔案來實驗。程式仍然可以執行，這表明了允許動態的、按需的載入分類；若不需要某一分類提供的功能，可以簡單的不編譯之。

### 扮演

Objective-C 允許一個類在程式中完全取代另一個類，這種行為稱為前者「扮演」(Posing) 目標類。

注意：類的扮演在 Mac OS X v10.5 中被廢棄，在 64 位元執行時中不可用。

### #import

在 C 語言中，`#include` 預處理指令總是使被包含的檔案內容被插入指令點。在 Objective-C 中，類似的指令 `#import` 保證一個檔案只會被包含一次，類似於一般標頭檔中的

慣用法，或 MSVC 中的

## 語言變化

### Objective-C++

Objective-C++ 是 GCC 的一個前端，它可以編譯混合了 C++ 與 Objective-C 語法的原始檔。Objective-C++ 是 C++ 的擴充，類似於 Objective-C 是 C 的擴充。由於在融合 C++ 與 Objective-C 兩種語言的特性方面沒有做特別的工作，因此有以下限制：

* C++ 類別不能從 Objective-C 類繼承，反之亦然。
* Objective-C 定義內部不能定義 C++ 命名空間。
* Objective-C 類的成員變數不能包括不含預設建構函式和 / 或含有虛方法的 C++ 類別物件，但使用 C++ 類別指標並無如此限制（可以在 -init 方法中對之進行初始化）。
* C++「傳遞值」的特性不能用在 Objective-C 物件上，而只能傳遞其指標。
* Objective-C 聲明不能存在在 C++ 模板聲明中，反之亦然。但 Objective-C 類型可以用在 C++ 模板的參數中。
* Objective-C 和 C++ 的錯誤處理語句不同，各自的語句只能處理各自的錯誤。
* Objective-C 錯誤使得 C++ 物件被登出時，C++ 解構函式不會被呼叫。新的 64 位元執行時解決了這個問題。

### Objective-C 2.0

在 2006 年 7 月蘋果全球開發者會議中，Apple 宣布了「Objective-C 2.0」的發布，其增加了「現代的垃圾收集，語法改進，執行時效能改進，以及 64 位元支援」。2007 年 10 月發布的 Mac OS X v10.5 中包含了 Objective-C 2.0 的編譯器。

#### 垃圾收集

Objective-C 2.0 提供了一個可選的垃圾收集器。在向下相容模式中，Objective-C 執行時會將參照計數操作，例如「retain」與「release」變為無操作。當垃圾收集啟用時，所有的物件都是收集器的工作物件。普通的 C 指標可以以「\_\_strong」修飾，標記指標指向的物件仍在使用中。被標記為「\_\_weak」的指標不被計入收集器的計數中，並在物件被回收時覆寫為「nil」。iOS 上的 Objective-C 2.0 實現中不包含垃圾收集器。垃圾收集器執行在一個低優先級的後台執行緒中，並可以在使用者動作時暫停，從而保持良好的使用者體驗。

#### 屬性

Objective-C 2.0 引入了新的語法以聲明變數為屬性 (編程)，並包含一可選定義以組態存取方法的生成。屬性總是為公共的，其目的為提供外部類存取（也可能為唯讀）類的內部變數的方法。屬性可以被聲明為「readonly」，即唯讀的，也可以提供儲存方法包括「assign」，「copy」或「retain」（簡單的賦值、複製或增加 1 參照計數）。預設的屬性是原子的，即在存取時會加鎖以避免多執行緒同時存取同一物件，也可以將屬性聲明為「nonatomic」（非原子的），避免產生鎖。

屬性的存取方法由 @synthesize 關鍵字來實現，它由屬性的聲明自動的產生一對存取方法。另外，也可以選擇使用 @dynamic 關鍵字表明存取方法會由程式設計師手工提供。

屬性可以利用傳統的訊息表達式、點表達式或 "valueForKey:"/"setValue:forKey:" 方法對來存取。

為了利用點表達式來存取實例的屬性，需要使用「self」關鍵字：

類或協定的屬性可以被動態的讀取。

#### 快速列舉

比起利用 NSEnumerator 物件或在集合中依次列舉，Objective-C 2.0 提供了快速列舉的語法。在 Objective-C 2.0 中，以下迴圈的功能是相等的，但效能特性不同。

快速列舉可以比標準列舉產生更有效的代碼，由於列舉所呼叫的方法被使用 NSFastEnumeration 協定提供的指標算術運算所代替了。

### Modern Objective-C

蘋果公司在 WWDC2012 大會上介紹了大量 Objective-C 的新特性，能夠讓程式設計師更加高效地編寫代碼，這些新特性在 Xcode4.4 版本中已經可以使用。

* Object Literals
* 預設生成 @synthesize 代碼
* 遍曆元素
* Subscripting Methods

## 語言分析

Objective-C 是非常「實際」的語言。它用一個很小的、用 C 寫成的執行庫，使得應用程式的大小增加很少，與此相比，大部分 OO 系統需要極大的執行時虛擬機器來執行。Objective-C 寫成的程式通常不會比其原始碼和函式庫（通常無需包含在軟體發行版本中）大太多，不會像 Smalltalk 系統，即使只是打開一個窗口也需要大量的記憶體。由於 Objective-C 的動態型別特徵，Objective-C 不能對方法進行行內（inline）一類的最佳化，使得 Objective-C 的應用程式一般比類似的 C 或 C++ 程式更大。

Objective-C 可以在現存 C 編譯器基礎上實現（在 GCC 中，Objective-C 最初作為預處理器引入，後來作為模組存在），而不需要編寫一個全新的編譯器。這個特性使得 Objective-C 能利用大量現存的 C 代碼、庫、工具和編程思想等資源。現存 C 庫可以用 Obj-C 包裝器來提供一個 Objective-C 使用的 OO 風格介面包裝。

以上這些特性極大地降低了進入 Objective-C 的門檻，這是 1980 年代 Smalltalk 在推廣中遇到的最大問題。

## 爭議

在最初的版本，Objective-C 並不支援垃圾回收；此事在當時是爭論的焦點之一。很多人考慮到 Smalltalk 回收時有漫長的「死亡時間」，令整個系統失去功用， Objective-C 為避免此問題才不實現垃圾回收。某些第三方版本加入了這個功能（例如 GNUstep），而蘋果公司最終也在其 Mac OS X 10.5 版本中實現了垃圾回收。

另一個廣受批評的問題是 Objective-C 不包括命名空間機制。取而代之的是程式設計師必須在其類別名稱加上前綴，由於字首往往較短（相比命名空間），這時常引致衝突。在 2007 年，在 Cocoa 編程環境中，所有 Mac OS X 類別和函式均有「NS」作為前綴，例如 NSObject 或 NSButton 來清楚分辨它們屬於 Mac OS X 核心；使用「NS」是由於這些類別的名稱在 NeXTSTEP 開發時定下。

雖然 Objective-C 是 C 的嚴格母集，但它也不視 C 語言的基本型別為第一級的物件。

和 C++ 不同，Objective-C 不支援運算子多載（它不支援特設多型）。亦與 C++ 不同，但和 Java 相同，Objective-C 只容許物件繼承一個類別（不設多重繼承）。Categories 和 protocols 不但可以提供很多多重繼承的好處，而且沒有很多缺點，例如額外執行時間過重和二進位不相容。

由於 Objective-C 使用動態執行時類型，而且所有的方法都是函式呼叫（有時甚至連系統呼叫（syscalls）也如此），很多常見的編譯時效能最佳化方法都不能應用於 Objective-C（例如：行內函式、常數傳播、互動式最佳化、聚集的純量取代等）。這使得 Objective-C 效能劣於類似的物件抽象語言（如 C++）。不過 Objective-C 擁護者認為 Objective-C 本就不應應用於 C++ 或 Java 常見的底層抽象，Objective-C 的應用方向是對效能要求不大的應用

## 參考文獻

## 外部連結

* 蘋果官方 Objective-C 開發說明文件（頁面存檔備份，存於網際網路檔案館）
* Objective-C 教學（頁面存檔備份，存於網際網路檔案館）