ObjectiveC 是一種通用、高階、面向物件的程式語言。它擴充套件了標準的 ANSI C 程式語言，將 Smalltalk 式的訊息傳遞機制加入到 ANSI C 中。目前主要支援的編譯器有 GCC 和 Clang（採用 LLVM 作為後端）。 ObjectiveC 的商標權屬於蘋果公司，蘋果公司也是這個程式語言的主要開發者。蘋果在開發 NeXTSTEP 作業系統時使用了 ObjectiveC，之後被 macOS、iPadOS、watchOS 和 iOS 繼承下來。現在 ObjectiveC 與 Swift 是 OS X 和 iOS 作業系統、及與其相關的 API、Cocoa 和 Cocoa Touch 的主要程式語言。 歷史 ObjectiveC 主要由 公司的布萊德考克斯（Brad Cox）和（Tom Love）在 1980 年代發明。 1981 年，考克斯和洛夫還在 ITT 公司技術中心任職時，他們接觸到了 Smalltalk。考克斯當時對軟體設計和開發問題非常感興趣，他很快地意識到 SmallTalk 在系統工程構建中具有無法估量的價值，但同時他和洛夫也明白，目前 ITT 公司的電子通訊工程相關技術中，C 語言被放在很重要的位置。 於是考克斯撰寫了一個 C 語言的前處理器，打算使 C 語言具備些許 Smalltalk 的本領。他很快地實現了一個可用的 C 語言擴充套件，此即為 ObjectiveC 語言的前身。到了 1983 年，考克斯與洛夫合夥成立了 Productivity Products International（PPI）公司，將 ObjectiveC 及其相關函式庫商品化販售，並在之後將公司改名為 StepStone。1986 年，考克斯出版了一本關於 ObjectiveC 的重要著作《ObjectOriented Programming An Evolutionary Approach》，書內詳述了 ObjectiveC 的種種設計理念。 1988 年，斯蒂夫喬布斯（Steve Jobs）離開蘋果公司後成立了 NeXT Computer 公司，NeXT 公司買下 ObjectiveC 語言的授權，並擴充套件了著名的開源編譯器 GCC 使之支援 ObjectiveC 的編譯。NeXT 公司基於 ObjectiveC 開發了 與 等函式庫，作為 NeXTSTEP 的的使用者介面與開發環境的基礎。雖然 NeXT 工作站後來在市場上失敗了，但 NeXT 上的軟體工具卻在業界中被廣泛讚揚。這促使 NeXT 公司放棄硬體業務，轉型為銷售 NeXTStep（以及 OpenStep）平臺為主的軟體公司。 1992 年，自由軟體基金會的 GNU 開發環境增加了對 ObjectiveC 的支援。1994 年，NeXT Computer 公司和 Sun Microsystem 聯合釋出了一個針對 NEXTSTEP 系統的標準典範，名為 OPENSTEP。OPENSTEP 在自由軟體基金會的實現名稱為 GNUstep。1996 年 12 月 20 日，蘋果公司宣佈收購 NeXT Software 公司，NEXTSTEPOPENSTEP 環境成為蘋果作業系統下一個主要發行版本 OS X 的基礎。這個開發環境的版本被蘋果公司稱為 Cocoa。 2005 年，蘋果電腦僱用了克里斯拉特納及 LLVM 開發團隊 Adam Treat mkspecs and patches for LLVM compile of Qt4 ，clang 及 LLVM 成為蘋果公司在 GCC 之外的新編譯器選擇，在 Xcode 40 之後均採用 LLVM 作為預設的編譯器。最新的 Modern ObjectiveC 特性也都率先在 Clang 上實現。 語法 ObjectiveC 是 C 語言的嚴格超集－－任何 C 語言程式不經修改就可以直接透過 ObjectiveC 編譯器，在 ObjectiveC 中使用 C 語言程式碼也是完全合法的。ObjectiveC 被描述為 蓋在 C 語言上的薄薄一層，因為 ObjectiveC 的原意就是在 C 語言主體上加入面向物件的特性。ObjectiveC 的面向物件語法源於 Smalltalk 訊息傳遞風格。所有其他非面向物件的語法，包括變數型別，前處理器（preprocessing），流程控制，函式宣告與呼叫皆與 C 語言完全一致。但有些 C 語言語法合法程式碼在 objectivec 中表達的意思不一定相同，比如某些布林表示式，在 C 語言中返回值為 true，但在 ObjectiveC 若與 true 直接相比較，函式將會出錯，因為在 ObjectiveC 中 true 的值只表示為 1。 Hello World 這裡示範了一個基礎的 Hello World 程式。基於 Xcode 431： import FoundationFoundationh int main int argc char argv autoreleasepool NSLog Hello World return 0 訊息傳遞 ObjectiveC 最大的特色是承自 Smalltalk 的訊息傳遞模型（message passing），此機制與今日 C 式之主流風格差異甚大。ObjectiveC 裡，與其說物件互相呼叫方法，不如說物件之間互相傳遞訊息更為精確。此二種風格的主要差異在於呼叫方法 訊息傳遞這個動作。C 裡類別與方法的關係嚴格清楚，一個方法必定屬於一個類別，而且在編譯時（compile time）就已經緊密繫結，不可能呼叫一個不存在類別裡的方法。但在 ObjectiveC，類別與訊息的關係比較鬆散，呼叫方法視為對物件傳送訊息，所有方法都被視為對訊息的回應。所有訊息處理直到執行時（runtime）才會動態決定，並交由類別自行決定如何處理收到的訊息。也就是說，一個類別不保證一定會回應收到的訊息，如果類別收到了一個無法處理的訊息，程式只會丟擲異常，不會出錯或崩潰。 C 裡，送一個訊息給物件（或者說呼叫一個方法）的語法如下： objmethod argument ObjectiveC 則寫成： obj method argument 此二者並不僅僅是語法上的差異，還有基本行為上的不同。 這裡以一個汽車類（car class）的簡單例子來解釋 ObjectiveC 的訊息傳遞特性： car fly 典型的 C 意義解讀是「呼叫 car 類別的 fly 方法」。若 car 類別裡頭沒有定義 fly 方法，那編譯肯定不會透過。但是 ObjectiveC 裡，我們應當解讀為「發送出一個 fly 的訊息給 car 物件」，fly 是訊息，而 car 是訊息的接收者。car 收到訊息後會決定如何回應這個訊息，若 car 類別內定義有 fly 方法就執行方法內之程式碼，若 car 內不存在 fly 方法，則程式依舊可以透過編譯，執行期則丟擲異常。 此二種風格各有優劣。C 強制要求所有的方法都必須有對應的動作，且編譯期繫結使得函式呼叫非常快速。缺點是僅能藉由 virtual 關鍵字提供有限的動態繫結能力。ObjectiveC 天生即具備鴨子型別之動態繫結能力，因為執行期才處理訊息，允許傳送未知訊息給物件。可以送訊息給整個物件集合而不需要一一檢查每個物件的型態，也具備訊息轉送機制。同時空物件 nil 接受訊息後預設為不做事，所以送訊息給 nil 也不用擔心程式崩潰。 類的定義與實現 ObjectiveC 中強制要求將類的介面（interface）與實現（implementation）分為兩個部分。 類的定義檔案遵循 C 語言之慣例以h 為字尾，實現檔案以m 為字尾。 介面 定義部分，清楚定義了類的名稱、成員變數和方法。 以關鍵字 interface 作為開始，end 作為結束。 interface MyObject NSObject int memberVar1 實體變數 id memberVar2 return_type class_method 類方法 return_type instance_method1 例項方法 return_type instance_method2 int p1 return_type instance_method3 int p1 andPar int p2 end 方法前面的 號代表函式的型別：加號代表類方法（class method），不需要例項就可以呼叫，與 C 的靜態函式（static member function）相似。減號即是一般的例項方法（instance method）。 這裡提供了一份意義相近的 C 語法對照，如下： class MyObject public NSObject protected int memberVar1 實體變數 void memberVar2 public static return_type class_method 類方法 return_type instance_method1 例項方法 return_type instance_method2 int p1 return_type instance_method3 int p1 int p2 ObjectiveC 定義一個新的方法時，名稱內的冒號代表引數傳遞，不同於 C 語言以數學函式的括號來傳遞引數。ObjectiveC 方法使得引數可以夾雜於名稱中間，不必全部附綴於方法名稱的尾端，可以提高程式可讀性。設定顏色 RGB 值的方法為例： void setColorToRed float red Green float green Bluefloat blue 宣告方法 myColor setColorToRed 10 Green 08 Blue 02 呼叫方法 這個方法的簽名是 setColorToRedGreenBlue。每個冒號後面都帶著一個 float 類別的引數，分別代表紅，綠，藍三色。 實現 實現區段則包含了公開方法的實現，以及定義私有（private）變數及方法。 以關鍵字 implementation 作為區段起頭，end 結尾。 implementation MyObject int memberVar3 私有實體變數 return_type class_method method implementation return_type instance_method1 return_type instance_method2 int p1 return_type instance_method3 int p1 andPar int p2 end 值得一提的是不只 Interface 區段可定義實體變數，Implementation 區段也可以定義實體變數，兩者的差別在於存取許可權的不同，Interface 區段內的實體變數預設許可權為 protected，宣告於 implementation 區段的實體變數則預設為 private，故在 Implementation 區段定義私有成員更符合物件導向之封裝原則，因為如此類別之私有資訊就不需曝露於公開 interface（h 檔案）中。 建立物件 ObjectiveC 建立物件需透過 alloc 以及 init 兩個訊息。alloc 的作用是分配記憶體，init 則是初始化物件。 init 與 alloc 都是定義在 NSObject 裡的方法，父物件收到這兩個資訊並做出正確回應後，新物件才建立完畢。以下為範例： MyObject my MyObject alloc init 在 ObjectiveC 20 裡，若建立物件不需要引數，則可直接使用 new MyObject my MyObject new 僅僅是語法上的精簡，效果完全相同。 若要自己定義初始化的過程，可以重寫 init 方法，來新增額外的工作。（用途類似 C 的建構函式 constructor） id init if selfsuper init 必須呼叫父類的 init do something here return self 協議 協議是一組沒有實現的方法列表，任何的類均可採納協議並具體實現這組方法。 ObjectiveC 在 NeXT 時期曾經試圖引入多重繼承的概念，但由於協議的出現而沒有實現之。 協議類似於 Java 與 C 語言中的 介面。在 ObjectiveC 中，有兩種定義協議的方式：由編譯器保證的 正式協議，以及為特定目的設定的 非正式協議。 非正式協議為一個可以選擇性實現的一系列方法列表。非正式協議雖名為協議，但實際上是掛於 NSObject 上的未實現分類（Unimplemented Category）的一種稱謂，ObjetiveC 語言機制上並沒有非正式協議這種東西，OSX 106 版本之後由於引入 optional 關鍵字，使得正式協議已具備同樣的能力，所以非正式協議已經被廢棄不再使用。 正式協議類似於 Java 中的 介面，它是一系列方法的列表，任何類都可以宣告自身實現了某個協議。在 ObjectiveC 20 之前，一個類必須實現它宣告符合的協議中的所有方法，否則編譯器會報告錯誤，表明這個類沒有實現它宣告符合的協議中的全部方法。ObjectiveC 20 版本允許標記協議中某些方法為可選的（Optional），這樣編譯器就不會強制實現這些可選的方法。 協議經常應用於 Cocoa 中的委託及事件觸發。例如文字框類通常會包括一個委託（delegate）物件，該物件可以實現一個協議，該協議中可能包含一個實現文字輸入的自動完成方法。若這個委託物件實現了這個方法，那麼文字框類就會在適當的時候觸發自動完成事件，並呼叫這個方法用於自動完成功能。 ObjectiveC 中協議的概念與 Java 中介面的概念並不完全相同，即一個類可以在不宣告它符合某個協議的情況下，實現這個協議所包含的方法，也即實質上符合這個協議，而這種差別對外部程式碼而言是不可見的。正式協議的宣告不提供實現，它只是簡單地表明符合該協議的類實現了該協議的方法，保證呼叫端可以安全呼叫方法。 語法 協議以關鍵字 protocol 作為區段起始，end 結束，中間為方法列表。 protocol Locking void lock void unlock end 這是一個協議的例子，多執行緒程式設計中經常要確保一份共享資源同時只有一個執行緒可以使用，會在使用前給該資源掛上鎖 ，以上即為一個表明有 鎖 的概念的協議，協議中有兩個方法，只有名稱但尚未實現。 下面的 SomeClass 宣稱他採納了 Locking 協議： interface SomeClass SomeSuperClass Locking end 一旦 SomeClass 表明他採納了 Locking 協議，SomeClass 就有義務實現 Locking 協議中的兩個方法。 implementation SomeClass void lock 實現 lock 方法 void unlock 實現 unlock 方法 end 由於 SomeClass 已經確實遵從了 Locking 協議，故呼叫端可以安全的傳送 lock 或 unlock 訊息給 SomeClass 實體變數，不需擔心他沒有辦法回應訊息。 外掛是另一個使用抽象定義的例子，可以在不關心外掛的實現的情況下定義其希望的行為。 動態型別 類似於 Smalltalk，ObjectiveC 具備動態型別：即訊息可以傳送給任何物件實體，無論該物件實體的公開介面中有沒有對應的方法。對比於 C 這種靜態型別的語言，編譯器會擋下對（void）指標呼叫方法的行為。但在 ObjectiveC 中，你可以對 id 傳送任何訊息（id 很像 void，但是被嚴格限制只能使用在物件上），編譯器僅會發出「該物件可能無法回應訊息」的警告，程式可以透過編譯，而實際發生的事則取決於執行期該物件的真正形態，若該物件的確可以回應訊息，則依舊執行對應的方法。 一個物件收到訊息之後，他有三種處理訊息的可能手段，第一是回應該訊息並執行方法，若無法回應，則可以轉發訊息給其他物件，若以上兩者均無，就要處理無法回應而拋出的例外。只要進行三者之其一，該訊息就算完成任務而被丟棄。若對 nil（空物件指標）傳送訊息，該訊息通常會被忽略，取決於編譯器選項可能會丟擲例外。 雖然 ObjectiveC 具備動態型別的能力，但編譯期的靜態型別檢查依舊可以應用到變數上。以下三種宣告在執行時效力是完全相同的，但是三種宣告提供了一個比一個更明顯的型別資訊，附加的型別資訊讓編譯器在編譯時可以檢查變數型別，並對型別不符的變數提出警告。 下面三個方法，差異僅在於引數的形態： setMyValueid foo id 形態表示引數 foo 可以是任何類的例項。 setMyValueid aProtocol foo idaProtocol 表示 foo 可以是任何類的例項，但必須採納 aProtocol 協議。 setMyValueNSNumber foo 該宣告表示 foo 必須是 NSNumber 的例項。 動態型別是一種強大的特性。在缺少泛型的靜態型別語言（如 Java 5 以前的版本）中實現容器類時，程式設計師需要寫一種針對通用型別物件的容器類，然後在通用型別和實際型別中不停的強制型別轉換。無論如何，型別轉換會破壞靜態型別，例如寫入一個 整數 而將其讀取為 字串 會產生執行時錯誤。這樣的問題被泛型解決，但容器類需要其內容物件的型別一致，而對於動態型別語言則完全沒有這方面的問題。 轉發 ObjectiveC 允許對一個物件傳送訊息，不管它是否能夠響應之。除了響應或丟棄訊息以外，物件也可以將訊息轉發到可以響應該訊息的物件。轉發可以用於簡化特定的設計模式，例如觀測器模式或代理模式。 ObjectiveC 執行時在 Object 中定義了一對方法： 轉發方法： retval_t forwardSEL sel arglist_t args with GCC id forwardSEL sel marg_list args with NeXTApple systems 響應方法： retval_t performvSEL sel arglist_t args with GCC id performvSEL sel marg_list args with NeXTApple systems 希望實現轉發的物件只需用新的方法覆蓋以上方法來定義其轉發行為。無需重寫響應方法 performv，由於該方法只是單純的對響應物件傳送訊息並傳遞引數。其中，SEL 型別是 ObjectiveC 中訊息的型別。 例子 這裡包括了一個演示轉發的基本概念的程式示例。 Forwarderh import objcObjecth interface Forwarder Object id recipient 該物件是我們希望轉發到的物件。 property assign nonatomic id recipient end Forwarderm import Forwarderh implementation Forwarder synthesize recipient retval_t forward SEL sel arglist_t args 檢查轉發物件是否響應該訊息。 若轉發物件不響應該訊息，則不會轉發，而產生一個錯誤。 if recipient respondsTosel return recipient performv sel args else return self errorRecipient does not respond Recipienth import objcObjecth A simple Recipient object interface Recipient Object id hello end Recipientm import Recipienth implementation Recipient id hello printf Recipient says hellon return self end mainm import Forwarderh import Recipienth int main void Forwarder forwarder Forwarder new Recipient recipient Recipient new forwarderrecipient recipient Set the recipient 轉發者不響應 hello 訊息！該訊息將被轉發到轉發物件。 （若轉發物件響應該訊息） forwarder hello return 0 腳註 利用 GCC 編譯時，編譯器報告： gcc x objectivec Wnoimport Forwarderm Recipientm mainm lobjc mainm In function main mainm12 warning Forwarder does not respond tohello 如前文所提到的，編譯器報告 Forwarder 類不響應 hello 訊息。在這種情況下，由於實現了轉發，可以忽略這個警告。 執行該程式產生如下輸出： aout Recipient says hello 類別 Category 在 ObjectiveC 的設計中，一個主要的考慮即為大型程式碼框架的維護。結構化程式設計的經驗顯示，改進程式碼的一種主要方法即為將其分解為更小的片段。ObjectiveC 借用並擴充套件了 Smalltalk 實現中的 分類 概念，用以幫助達到分解程式碼的目的。 一個分類可以將方法的實現分解進一系列分離的檔案。程式設計師可以將一組相關的方法放進一個分類，使程式更具可讀性。舉例來講，可以在字串類中增加一個名為 拼寫檢查 的分類，並將拼寫檢查的相關程式碼放進這個分類中。 進一步的，分類中的方法是在執行時被加入類中的，這一特性允許程式設計師向現存的類中增加方法，而無需持有原有的程式碼，或是重新編譯原有的類。例如若系統提供的字串類的實現中不包含拼寫檢查的功能，可以增加這樣的功能而無需更改原有的字串類的程式碼。 在執行時，分類中的方法與類原有的方法並無區別，其程式碼可以存取包括私有類成員變數在內的所有成員變數。 若分類聲明瞭與類中原有方法同名的函式，則分類中的方法會被呼叫。因此分類不僅可以增加類的方法，也可以代替原有的方法。這個特性可以用於修正原有程式碼中的錯誤，更可以從根本上改變程式中原有類的行為。若兩個分類中的方法同名，則被呼叫的方法是不可預測的。 其它語言也嘗試了透過不同方法增加這一語言特性。在這方面走的更遠，不僅允許增加方法，更允許增加成員變數。也有其它語言使用面向宣告的解決方案，其中最值得注意的是 Self 語言。 C 與 Visual BasicNET 語言以的與不完全類的方式實現了類似的功能。Ruby 與一些動態語言則以 Monkey patch 的名字稱呼這種技術。 使用分類的例子 這個例子建立了 Integer 類，其本身只定義了 integer 屬性，然後增加了兩個分類 Arithmetic 與 Display 以擴充套件類的功能。雖然分類可以訪問類的私有成員，但通常利用屬性的存取方法來存取是一種更好的做法，可以使得分類與原有類更加獨立。這是分類的一種典型應用 另外的應用是利用分類來替換原有類中的方法，雖然用分類而不是繼承來替換方法不被認為是一種好的做法。 Integerh import objcObjecth interface Integer Object private int integer property assign nonatomic integer end Integerm import Integerh implementation Integer synthesize integer end Arithmetich import Integerh interface Integer Arithmetic id add Integer addend id sub Integer subtrahend end Arithmeticm import Arithmetich implementation Integer Arithmetic id add Integer addend selfinteger selfinteger addendinteger return self id sub Integer subtrahend selfinteger selfinteger subtrahendinteger return self end Displayh import Integerh interface Integer Display id showstars id showint end Displaym import Displayh implementation Integer Display id showstars int i x selfinteger for i0 i x i printf printf n return self id showint printf dn selfinteger return self end mainm import Integerh import Arithmetich import Displayh int main void Integer num1 Integer new num2 Integer new int x printf Enter an integer scanf d x num1integer x num1 showstars printf Enter an integer scanf d x num2integer x num2 showstars num1 addnum2 num1 showint return 0 註釋 可以利用以下命令來編譯： gcc x objectivec mainm Integerm Arithmeticm Displaym lobjc 在編譯時間，可以利用省略 import Arithmetich 與 num1 addnum2 命令，以及 Arithmeticm 檔案來實驗。程式仍然可以執行，這表明了允許動態的、按需的載入分類；若不需要某一分類提供的功能，可以簡單的不編譯之。 扮演 ObjectiveC 允許一個類在程式中完全取代另一個類，這種行為稱為前者 扮演Posing 目標類。 注意：類的扮演在 Mac OS X v105 中被廢棄，在 64 位執行時中不可用。 import 在 C 語言中，include 預處理指令總是使被包含的檔案內容被插入指令點。在 ObjectiveC 中，類似的指令 import 保證一個檔案只會被包含一次，類似於一般標頭檔案中的 ifndef XXX define XXX endif 慣用法，或 MSVC 中的 pragma once 語言變化 ObjectiveC ObjectiveC 是 GCC 的一個前端，它可以編譯混合了 C 與 ObjectiveC 語法的原始檔。ObjectiveC 是 C 的擴充套件，類似於 ObjectiveC 是 C 的擴充套件。由於在融合 C 與 ObjectiveC 兩種語言的特性方面沒有做特別的工作，因此有以下限制： C 類不能從 ObjectiveC 類繼承，反之亦然。 ObjectiveC 定義內部不能定義 C 名稱空間。 ObjectiveC 類的成員變數不能包括不含預設建構函式和 或含有虛方法的 C 類物件，但使用 C 類指標並無如此限制（可以在 init 方法中對之進行初始化）。 C傳遞值 的特性不能用在 ObjectiveC 物件上，而只能傳遞其指標。 ObjectiveC 宣告不能存在在 C 模板宣告中，反之亦然。但 ObjectiveC 型別可以用在 C 模板的引數中。 ObjectiveC 和 C 的錯誤處理語句不同，各自的語句只能處理各自的錯誤。 ObjectiveC 錯誤使得 C 物件被退出時，C 解構函式不會被呼叫。新的 64 位執行時解決了這個問題。Using C With ObjectiveC in Mac OS X Reference Library last retrieved in 20100210 ObjectiveC 20 在 2006 年 7 月蘋果全球開發者會議中，Apple 宣佈了 ObjectiveC 20 的釋出，其增加了 現代的垃圾收集，語法改進，執行時效能改進，以及 64 位支援。2007 年 10 月釋出的 Mac OS X v105 中包含了 ObjectiveC 20 的編譯器。 垃圾收集 ObjectiveC 20 提供了一個可選的垃圾收集器。在向後相容模式中，ObjectiveC 執行時會將引用計數操作，例如 retain 與 release 變為無操作。當垃圾收集啟用時，所有的物件都是收集器的工作物件。普通的 C 指標可以以 __strong 修飾，標記指標指向的物件仍在使用中。被標記為 __weak 的指標不被計入收集器的計數中，並在物件被回收時改寫為 nil。iOS 上的 ObjectiveC 20 實現中不包含垃圾收集器。垃圾收集器執行在一個低優先順序的後臺執行緒中，並可以在使用者動作時暫停，從而保持良好的使用者體驗。 屬性 ObjectiveC 20 引入了新的語法以宣告變數為屬性 程式設計，幷包含一可選定義以配置存取方法的生成。屬性總是為公共的，其目的為提供外部類存取（也可能為只讀）類的內部變數的方法。屬性可以被宣告為 readonly，即只讀的，也可以提供儲存方法包括 assign，copy 或 retain（簡單的賦值、複製或增加 1 引用計數）。預設的屬性是原子的，即在訪問時會加鎖以避免多執行緒同時訪問同一物件，也可以將屬性宣告為 nonatomic（非原子的），避免產生鎖。 interface Person NSObject public NSString name private int age property copy NSString name property readonly int age id initWithAgeint age end 屬性的存取方法由 synthesize 關鍵字來實現，它由屬性的宣告自動的產生一對存取方法。另外，也可以選擇使用 dynamic 關鍵字表明存取方法會由程式設計師手工提供。 implementation Person synthesize name dynamic age id initWithAgeint initAge age initAge 注意：直接賦給成員變數，而非屬性 return self int age return 29 注意：並非返回真正的年齡 end 屬性可以利用傳統的訊息表示式、點表示式或 valueForKeysetValueforKey 方法對來存取。 Person aPerson Person alloc initWithAge 53 aPersonname Steve 注意：點表示式，等於 aPerson setName Steve NSLog Access by message dot notation property name and direct instance variable access aPerson name aPersonname aPerson valueForKeyname aPersonname 為了利用點表示式來存取例項的屬性，需要使用 self 關鍵字： void introduceMyselfWithPropertiesBOOL useGetter NSLog Hi my name is useGetter selfname name NOTE getter vs ivar access 類或協議的屬性可以被動態的讀取。 int i int propertyCount 0 objc_property_t propertyList class_copyPropertyList aPerson class propertyCount for i0 i propertyCount i objc_property_t thisProperty propertyList i const char propertyName property_getName thisProperty NSLog Person has a property s propertyName 快速列舉 比起利用 NSEnumerator 物件或在集合中依次列舉，ObjectiveC 20 提供了快速列舉的語法。在 ObjectiveC 20 中，以下迴圈的功能是相等的，但效能特性不同。 使用 NSEnumerator NSEnumerator enumerator thePeople objectEnumerator Person p while p enumerator nextObject nil NSLog is i years old p name p age 使用依次列舉 for int i 0 i thePeople count i Person p thePeople objectAtIndexi NSLog is i years old p name p age 使用快速列舉 for Person p in thePeople NSLog is i years old p name p age 快速列舉可以比標準列舉產生更有效的程式碼，由於列舉所呼叫的方法被使用 NSFastEnumeration 協議提供的指標算術運算所代替了。 Modern ObjectiveC 蘋果公司在 WWDC2012 大會上介紹了大量 ObjectiveC 的新特性，能夠讓程式設計師更加高效地編寫程式碼，這些新特性在 Xcode44 版本中已經可以使用。 Object Literals 預設生成 synthesize 程式碼 遍歷元素 Subscripting Methods 語言分析 ObjectiveC 是非常「實際」的語言。它用一個很小的、用 C 寫成的執行庫，使得應用程式的大小增加很少，與此相比，大部分 OO 系統需要極大的執行時虛擬機器來執行。ObjectiveC 寫成的程式通常不會比其原始碼和函式庫（通常無需包含在軟體發行版本中）大太多，不會像 Smalltalk 系統，即使只是開啟一個視窗也需要大量的記憶體。由於 ObjectiveC 的動態型別特徵，ObjectiveC 不能對方法進行內聯（inline）一類的最佳化，使得 ObjectiveC 的應用程式一般比類似的 C 或 C 程式更大。 ObjectiveC 可以在現存基礎上實現（在 GCC 中，ObjectiveC 最初作為預處理器引入，後來作為模組存在），而不需要編寫一個全新的編譯器。這個特性使得 ObjectiveC 能利用大量現存的 C 程式碼、庫、工具和程式設計思想等資源。現存 C 庫可以用 ObjC 包裝器來提供一個 ObjectiveC 使用的 OO 風格介面包裝。 以上這些特性極大地降低了進入 ObjectiveC 的門檻，這是 1980 年代 Smalltalk 在推廣中遇到的最大問題。 爭議 在最初的版本，ObjectiveC 並不支援垃圾回收；此事在當時是爭論的焦點之一。很多人考慮到 Smalltalk 回收時有漫長的「死亡時間」，令整個系統失去功用， ObjectiveC 為避免此問題才不實現垃圾回收。某些第三方版本加入了這個功能（例如 GNUstep），而蘋果公司最終也在其 Mac OS X 105 版本中實現了垃圾回收。 ObjectiveC 不包括名稱空間機制，一直廣受批評。取而代之的是程式設計師必須在其類別名稱加上字首，由於字首往往較短（相比名稱空間），這時常引致衝突。在 2007 年，在 Cocoa 程式設計環境中，所有 Mac OS X 類別和函式均有「NS」作為字首，例如 NSObject 或 NSButton 來清楚分辨它們屬於 Mac OS X 核心；使用「NS」是由於這些類別的名稱在 NeXTSTEP 開發時定下。 雖然 ObjectiveC 是 C 的嚴格 zh 超集；zhhans 超集；zhhant 母集；zhcn 超集；zhtw 母集；，但它也不視 C 語言的基本 zh 型別；zhhans 型別；zhhant 型別；zhcn 型別；zhtw 型別； 為第一級的 zh 物件；zhhans 物件；zhhant 物件；zhcn 物件；zhtw 物件；。 和 C 不同，ObjectiveC 不支援運運算元多載（它不支援特設多型）。亦與 C 不同，但和 Java 相同，ObjectiveC 只容許物件繼承一個類別（不設多重繼承）。Categories 和 protocols 不但可以提供很多多重繼承的好處，而且沒有很多缺點，例如額外執行時間過重和二進位制不相容。 由於 ObjectiveC 使用動態執行時型別，而且所有的方法都是函式呼叫（有時甚至連 zh 系統呼叫；zhhans 系統呼叫；zhhant 系統呼叫；zhcn 系統呼叫；zhtw 系統呼叫；（syscalls）也如此），很多常見的編譯時效能最佳化方法都不能應用於 ObjectiveC（例如：行內函數、常數傳播、、聚集的純量取代等）。這使得 ObjectiveC 效能劣於類似的物件抽象語言（如 C）。不過 ObjectiveC 擁護者認為 ObjectiveC 本就不應應用於 C 或 Java 常見的底層抽象，ObjectiveC 的應用方向是對效能要求不大的應用。 參考文獻 外部連結 蘋果官方 ObjectiveC 開發說明文件 ObjectiveC 教學 CategoryC 語言家族 CategoryIOS 開發 Category 面向物件的程式語言 Category 基於類的程式語言 CategoryGNUstep Category1986 年建立的程式語言