Objective-C現(xiàn)代語(yǔ)法與新特性(2015)

Swift的確是一個(gè)很強(qiáng)大的語(yǔ)言梗掰,各種特性使用起來(lái)非常簡(jiǎn)潔強(qiáng)大,但是目前來(lái)說(shuō)头滔,感覺(jué)成熟度還是不夠,所以商業(yè)項(xiàng)目中使用OC來(lái)說(shuō)是比較穩(wěn)健的行為涎显±ぜ欤看來(lái)一下WWDC 2015的 Swift and Objective-C Interoperability session,視頻前半部分主要是講解swift和OC之間的交互的規(guī)則期吓,后面則講到OC的一部分新的語(yǔ)言特性早歇,這幾個(gè)特性,Apple的開(kāi)發(fā)人員在 WWDC上說(shuō)的那樣讨勤,對(duì)代碼的可讀性提升非常大箭跳,所以從swift中把這個(gè)特性引入到OC中,個(gè)人感覺(jué)也是為后續(xù)向swift的遷移提供支撐潭千,最主要的是 這些特性在iOS SDK中以及全面采用并且兼容低版本,所以可以在當(dāng)前工作中引入這些特性脊岳。

文章的前半部分記錄一些之前的Objective-C的現(xiàn)代語(yǔ)法,后面講解WWDC 2015中介紹的新特性割捅,詳細(xì)建議去觀看.WWDC 2015的視頻 ?WWDC 2015總結(jié)

【instancetype】

1. id 與 NSObject *

(1) id 是 Objective-C 對(duì)象,但是并不一定是NSObject對(duì)象莫瞬,并非所有的Foundation/Cocoa對(duì)象都是繼承于NSObject對(duì)象的,比如NSProxy旁振。同時(shí),id與NSObject對(duì)象之間有很多的共同方法涨岁,比如retain與release等方法拐袜。更一步來(lái)說(shuō):所有的對(duì)象本質(zhì)來(lái)說(shuō)都是 id 類(lèi)型的。

(2) 對(duì)于id來(lái)說(shuō)梢薪,你可以調(diào)用任意可見(jiàn)的selector蹬铺,編譯器和IDE不會(huì)進(jìn)行類(lèi)型檢查,這個(gè)時(shí)候就需要你自己進(jìn)行類(lèi)型檢查并且進(jìn)行類(lèi)型轉(zhuǎn)換秉撇,來(lái)確保這些調(diào)用不會(huì)出錯(cuò)甜攀。而對(duì)于NSObject *類(lèi)型秋泄,只能調(diào)用NSObject對(duì)象所聲明的selector,不能調(diào)用它子類(lèi)的selector赴邻,編譯器會(huì)進(jìn)行檢查印衔。

(3) 對(duì)于一些不想或者不能進(jìn)行類(lèi)型檢查的地方,可以使用id姥敛。比如在集合(array, collection)類(lèi)型中奸焙,比如在一些你并不知道方法的返回類(lèi)型的地方(比如alloc),比如我們經(jīng)常聲明delegate為id類(lèi)型彤敛,在運(yùn)行的時(shí)候再使用respondToSelector:來(lái)進(jìn)行檢查与帆。

2. id

使用id來(lái)聲明一個(gè)對(duì)象,相當(dāng)于告訴編譯我們并不知道這個(gè)對(duì)象的類(lèi)型墨榄,但是它實(shí)現(xiàn)NSObject protocol玄糟。一個(gè)這種類(lèi)型的指針,即可以用來(lái)指向NSObject*對(duì)象袄秩,也可以用來(lái)指向NSProxy*對(duì)象阵翎,因?yàn)镹SObject對(duì)象與NSProxy對(duì)象都是現(xiàn)了NSObject protocol。

3. id 與 instancetype

在instancetype有效的情況下之剧,應(yīng)該盡量去使用instancetype郭卫。至于什么是合適的時(shí)候,可以參考stack overflow上面所說(shuō):“Use instancetype whenever it's appropriate, which is whenever a class returns an instance of that same class.”背稼,http://stackoverflow.com/questions/8972221/would-it-be-beneficial-to-begin-using-instancetype-instead-of-id/14652187#14652187

Apple官方文檔:

In your code, replace occurrences ofidas a return value withinstancetypewhere appropriate. This is typically the case forinitmethods and class factory methods. Even though the compiler automatically converts methods that begin with “alloc,” “init,” or “new” and have a return type ofidto returninstancetype, it doesn’t convert other methods.Objective-C convention is to writeinstancetypeexplicitly for all methods.

【Properties】

使用Properties來(lái)代替實(shí)例變量有很多優(yōu)勢(shì):

Auto synthesized getters and setters. ?使用@property聲明的屬性能自動(dòng)生成getter與setter方法贰军。

Better declaration of intent of a set of methods. ?比為屬性聲明一系列方法代碼上要清晰很多。

Property keywords that express additional information about behavior. ?Property使用其他的一些關(guān)鍵子可以表達(dá)一些實(shí)例變量無(wú)法表達(dá)的信息蟹肘,比如 assign, weak, atomic等等词疼。

Property方法有一個(gè)非常簡(jiǎn)明的命名規(guī)范,getter方法的名稱(chēng)是property的名稱(chēng)帘腹,setter方法的名稱(chēng)是在property名稱(chēng)之前添加set前綴(駝峰法)贰盗。通過(guò)還可以通過(guò)getter關(guān)鍵字指定getter的名稱(chēng)。

在聲明一個(gè)Property的時(shí)候阳欲,需要記住下面這些不能是properties的:

init method

copy method, mutableCopy method

A class factory method

初始化一個(gè)action并返回一個(gè)BOOL結(jié)果的方法

A method that explicitly changes internal state as a side effect of a getter

【Enumration Marcos】

使用NS_ENUM來(lái)定義枚舉童太,使用NS_OPTIONS來(lái)定義options。這兩個(gè)宏可以改善Xcode中的代碼補(bǔ)全胸完,明確指出枚舉和options的類(lèi)型和大小书释。

【Object Initialization】

可能是為了兼容swift,OC中添加了 designated initializer 初始化方法和 convenience initializers 初始化方法:

designated initializer : 負(fù)責(zé)調(diào)用superclass的初始化方法以及初始化自己的實(shí)例變量的初始化方法

convenience initializers : 非designated initializer都被稱(chēng)為designated initializer赊窥。這些initializer內(nèi)部實(shí)現(xiàn)一般都是調(diào)用另外一個(gè)initializer爆惧,然而最終一系列鏈?zhǔn)秸{(diào)用之后,最終都會(huì)調(diào)用某 一個(gè)designated initializer 方法來(lái)進(jìn)行初始化行為锨能。

實(shí)現(xiàn)一個(gè)designated initializer方法很簡(jiǎn)單扯再,通過(guò)NS_DESIGNATED_INITIALIZER宏即可實(shí)現(xiàn)芍耘,但是使用designated initializer的時(shí)候,會(huì)有一些限制規(guī)則熄阻,跟swift中的這些規(guī)則非常類(lèi)似斋竞。詳情可以參考:https://developer.apple.com/library/ios/releasenotes/ObjectiveC/ModernizationObjC/AdoptingModernObjective-C/AdoptingModernObjective-C.html

WWDC 2015

【Nullability】

Nullability特性用來(lái)指明 Objective-C/C 指針是否可以為nil。顯然秃殉,使用這個(gè)特性更能清晰表達(dá)API的意圖坝初,同時(shí)可以提升編譯器的static checking,還有一點(diǎn)就可以提高這些API在swift中的可用性钾军。如果使用Xcode 7的話鳄袍,可能注意到在iOS SDK中這個(gè)特性已經(jīng)被大量采用了。下面這種截圖說(shuō)明了Nullability的用法吏恭。

OC是如何引入這個(gè)特性拗小,并且又讓低版本的iOS支持的呢?Apple稱(chēng)之為 Audited Regions樱哼,也就是下面這兩個(gè)宏之間的區(qū)域哀九,NS_ASSUME_NONNULL_BEGIN … NS_ASSUME_NONNULL_END。

Audited Regions對(duì)其中的指針做了一些默認(rèn)的假設(shè)搅幅,Single-level指針被認(rèn)為是nonnull的阅束,NSError**指針被認(rèn)為在各個(gè)指針 level上面都是nullable的。所以我們?cè)贏udited Regions內(nèi)只需要指明那些 nullable 或者 null_unspecified的場(chǎng)景盏筐。

在C指針中使用 Nullability 的話围俘,與OC中不同的地方在于砸讳,使用的nullability qualifier需要在前面添加雙下劃線琢融,并且要將nullability qualifier寫(xiě)在指針后面。例如下面:

Lightweight Generics

這個(gè)輕量級(jí)泛型簿寂,一方面會(huì)提高代碼可讀性漾抬,讓API變得更加清晰。另外一方面常遂,還能使編譯器會(huì)幫助我們做一些類(lèi)型檢查纳令,找到一些潛在的錯(cuò)誤,達(dá)到 Type Safety的效果克胳。

日常主要的用法是針對(duì)兩個(gè)集合類(lèi)的平绩,NSArray與NSDictionary,詳細(xì)用法可以參考官方SDK中的使用漠另。同時(shí)捏雌,我們也可以在我們自己的代碼來(lái)使用這個(gè)輕量級(jí)泛型,在自定義類(lèi)笆搓,category性湿,extension等等纬傲。

自定義類(lèi)中的使用語(yǔ)法:

Category / Extension的使用語(yǔ)法:

WWDC中還強(qiáng)調(diào)了一點(diǎn)是,Lightweight Generics 是向前兼容的肤频,不會(huì)更改OC的runtime叹括,同時(shí)也不會(huì)對(duì)生成的代碼造成任何影響。

__kindof

在OC中宵荒,我們的代碼中會(huì)大量使用id這個(gè)特性汁雷,這個(gè)特性用起來(lái)會(huì)帶來(lái)很多很方便的特性,但是它有個(gè)缺陷骇扇,我們經(jīng)常需要進(jìn)行強(qiáng)制類(lèi)型轉(zhuǎn)換摔竿。 Xcode 7中有個(gè)新特性,__kindof少孝,“Kindof” types express “some kind of X”继低,用__kind修飾的變量表示是某個(gè)類(lèi)或者這個(gè)類(lèi)的子類(lèi)。

當(dāng)我們把這個(gè)類(lèi)或者子類(lèi)的其他變量賦值給這個(gè)變量時(shí)稍走,編譯器會(huì)默認(rèn)幫我們進(jìn)行類(lèi)型轉(zhuǎn)換以及類(lèi)型檢查工作袁翁,這樣就不需要我們寫(xiě)一些強(qiáng)制類(lèi)型轉(zhuǎn)換這樣 的代碼了。最簡(jiǎn)單的一個(gè)例子是在UITableView的應(yīng)用婿脸,cellForRowAtIndexPath:返回的變量使用這個(gè)修飾之后粱胜,我們就不再需 要寫(xiě)任何強(qiáng)制類(lèi)型轉(zhuǎn)換了,例如狐树,CustomCell *cell = [tableview cellForRowAtIndexPath:indexPath];

同時(shí)焙压,我們可以將Kindof types和lightweight generics結(jié)合在一起,比如官方提供的特性:

關(guān)于id類(lèi)型

看了上面這些新特性之后抑钟,你會(huì)發(fā)現(xiàn)在平時(shí)開(kāi)發(fā)中涯曲,你真的還需要那么多id嗎?大多數(shù)情況下在塔,我們都可以使用一個(gè)更加精確的類(lèi)型表示幻件,這樣能避免一些例如 type safety的問(wèn)題,同時(shí)也能讓代碼更加清晰蛔溃。下面看一下官方指明的替代id的情景:

在返回 “self” 的方法中绰沥,使用instancetype來(lái)代替id

大多數(shù) Collections 都可以變成 Typed Collections 來(lái)代替id

__kindof X * 來(lái)表示 “some subclass of X”,而不再使用id贺待,可以減少類(lèi)型強(qiáng)制轉(zhuǎn)換之類(lèi)的代碼

id 表示conforms to SomeProtocol的任意類(lèi)型

那什么情況下使用id呢徽曲?只有那些你確認(rèn)要表示”an object of any type”的時(shí)候再使用id,否則麸塞,盡量使用其他語(yǔ)法代替id秃臣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市喘垂,隨后出現(xiàn)的幾起案子甜刻,更是在濱河造成了極大的恐慌绍撞,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件得院,死亡現(xiàn)場(chǎng)離奇詭異傻铣,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)祥绞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)非洲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人蜕径,你說(shuō)我怎么就攤上這事两踏。” “怎么了兜喻?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵梦染,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我朴皆,道長(zhǎng)帕识,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任遂铡,我火速辦了婚禮肮疗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘扒接。我一直安慰自己伪货,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布钾怔。 她就那樣靜靜地躺著碱呼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蒂教。 梳的紋絲不亂的頭發(fā)上巍举,一...
    開(kāi)封第一講書(shū)人閱讀 51,146評(píng)論 1 297
  • 那天脆荷,我揣著相機(jī)與錄音凝垛,去河邊找鬼。 笑死蜓谋,一個(gè)胖子當(dāng)著我的面吹牛梦皮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播桃焕,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼剑肯,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了观堂?” 一聲冷哼從身側(cè)響起让网,我...
    開(kāi)封第一講書(shū)人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤呀忧,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后溃睹,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體而账,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年因篇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了泞辐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡竞滓,死狀恐怖咐吼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情商佑,我是刑警寧澤锯茄,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站茶没,受9級(jí)特大地震影響撇吞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜礁叔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一牍颈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧琅关,春花似錦煮岁、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至新症,卻和暖如春步氏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背徒爹。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工荚醒, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人隆嗅。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓界阁,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親胖喳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子泡躯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容