在查 NSURLConnection 的時候, 看到一堆重要的 method 被 deprecated 了, 感到相當困惑。讀了這篇說明才明白, 原來東西都在, 用法其實也沒什麼變, 只是宣告的方式變了。
首先要理解 Objective-C 的語法 Category:
@interface SomeClass (SomeCategory) ... @end
在 ... 宣告的方法, 是對 SomeClass 的擴充, 這組擴充的名稱為 SomeCategory。
Category 可用在包含標準函式庫 (Foundation) 內的任何 class。這有什麼好處呢? 比方說你需要一個比較特別的 Set 操作, 像是 [mySet uniformRandomObject] 傳回 mySet 內隨機的一個物件。不論是用組合還是繼承的方式訂新的 class, 都不太方便。這時用 Category 就很方便了:
// NSSet+RandomOps.h @interface NSSet (RandomOps) -(id)uniformRandomObject; @end // NSSet+RandomOps.m @implementation NSSet (RandomOps) -(id)uniformRandomObject { ... } @end
再來, Protocol 相當於 Java 的 interface, 也就是只有宣告但不帶實作的介面。另一方面, 只有宣告 Category 卻沒有提供實作的宣告, 就稱為 Informal Protocol。通常會宣告在 NSObject 上, 這樣任何客戶碼都可以實作需要的 method 而不用繼承其它 class。 NSURLConnection deprecated 的那些方法就是採用此方法。在 iOS 4.3 to iOS 5.0 API Differences 搜尋 "NSURLConnection.h" 可看到多數 callback 從 NSObject 裡移到新的 protocol NSURLConnectionDelegate、NSURLConnectionDataDelegate、NSURLConnectionDownloadDelegate 裡面。
Objective-C 2.0 以前 protocol 沒有 @optional 的語法。若希望 delegate 可以選擇性實作 callback methods, 只能使用 Informal Protocol。有了 @optional 語法後, 比較不需要用到 Informal Protocol。
Btw, Objective-C 同時有 static typing 和 dynamic typing 的效果, 還滿神奇的。不知當年訂這語言的人在想什麼, 雖然我喜歡使用 Python, 不過更偏好 static typing, 待用更多 Objective-C 後再來體會這種組合的優缺點。
就我的理解 Objective-C runtime 基本上是 dynamic typing 的, static typing 僅存在 syntax checking 而已. 就連 method (objective-C似乎稱為selector)的 signature 也是不含型別的. 你可以用 id 這個型別來存取任何 objective-C object.
回覆刪除我的理解和你一樣, 差別在於我們用詞的定義可能不同。雖說用詞的定義比較次要, 保險起見查一下 wikipedia:
回覆刪除http://en.wikipedia.org/wiki/Type_system#Type_checking
A programming language is said to use static typing when type checking is performed during compile-time as opposed to run-time
A programming language is said to be dynamically typed when the majority of its type checking is performed at run-time as opposed to at compile-time.
結果 Objective-C 本身的介紹是寫: Typing discipline static, dynamic, weak
http://en.wikipedia.org/wiki/Objective-C
分不清那邊比較多, 就兩者都寫上去了 XD
Btw, 寫 Python 的時候, 最大的不滿就是做些小修改也得跑一次程式才可確定沒有改爛, 有 compiler 幫忙抓出主要錯誤, 省事許多。
Btw (2), 最近學 Objective-C 才明白為什麼 Objective-C++ 沒有抓出未實作 pure virtual method 的錯誤 (也可能是 compiler bug), 以前覺得這滿不合理的, 當時誤以為它如同 C/C++ 是「純種」 static typing, 現在就釋懷多了