自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Objective-C 語(yǔ)言的命名空間詳解

移動(dòng)開發(fā) iOS
就像父母要向孩子解釋“什么是死亡”或者“圣誕老人是不存在的”問(wèn)題一樣,父母總是寄希望時(shí)間會(huì)讓孩子自己找到答案。為什么Objecive-C中的很多類名都是NS開頭的呢?實(shí)際上NS代表了NeXTSTEP。

“為什么Objecive-C中的很多類名都是NS開頭的呢?”

我保證在你第一次給別人介紹Objective-C的時(shí)候肯定會(huì)聽到這句話。

就像父母要向孩子解釋“什么是死亡”或者“圣誕老人是不存在的”問(wèn)題一樣,父母總是寄希望時(shí)間會(huì)讓孩子自己找到答案。

你既然這么問(wèn)了,實(shí)際上NS代表了NeXTSTEP (好吧,其實(shí)是代表NeXTSTEP/Sun,我們只是做個(gè)簡(jiǎn)單的介紹),它被用于…

你越解釋,你會(huì)發(fā)現(xiàn)對(duì)方越失望,接下來(lái),他們不在只是隨便問(wèn)問(wèn)了,他們開始問(wèn)一些你更難解釋的問(wèn)題–在Objective-C中@是什么?

命名一直是Objective-C的硬傷,和那些優(yōu)雅的語(yǔ)言相比,Objective-C缺乏標(biāo)識(shí)符容器這點(diǎn)引來(lái)了很多不切實(shí)際的批評(píng)家。

他們總是說(shuō):Objective-C不像其他流行語(yǔ)言一樣提供模塊化機(jī)制來(lái)避免類名和方法名的沖突。

相反地,Objective-C 依靠前綴來(lái)確保APP中的一些地方的方法名不會(huì)影響其他的地方有相同名字的代碼。

插入一個(gè)關(guān)于類型系統(tǒng)的題外話之后我們會(huì)繼續(xù)進(jìn)入關(guān)于命名的討論。

C和Objective-C中的類型

我曾在這博客上多次提過(guò),Objective-C是直接建立在C語(yǔ)言之上的,一個(gè)重要的原因是Objective-C和C語(yǔ)言共用一個(gè)類型系統(tǒng),他們都要求標(biāo)識(shí)符是全局唯一的。

你可以自己定義一個(gè)和@interface同名的靜態(tài)變量,編譯之后你會(huì)得到一個(gè)錯(cuò)誤:

  1. @interface XXObject : NSObject 
  2. @end 
  3.   
  4. static char * XXObject;//將“XXObject”重新定義為不同的符號(hào) 

也就是說(shuō),Objective-C的runtime在C語(yǔ)言的類型系統(tǒng)上又創(chuàng)建了一個(gè)抽象層,它甚至可以允許下面這段代碼被編譯:

  1. @protocol Foo 
  2. @end 
  3.   
  4. @interface Foo : NSObject <Foo 
  5.     id Foo 
  6.   
  7. @property id Foo; 
  8. + (id)Foo; 
  9. - (id)Foo; 
  10. @end 
  11.   
  12. @interface Foo (Foo) 
  13. @end 
  14.   
  15. @implementation Foo 
  16. @synthesize Foo; 
  17.   
  18. + (id)Fo 
  19.     id Foo = @"Fo 
  20.     return Foo 
  21. @end 

通過(guò)Objective-C的環(huán)境,程序能區(qū)別所有相同名字的類,協(xié)議,類別,實(shí)例變量,實(shí)例方法和類方法。

一個(gè)變量能重新調(diào)整一個(gè)已經(jīng)存在的方法也是得益與C語(yǔ)言的類型系統(tǒng)(這個(gè)有點(diǎn)像一個(gè)變量能夠隱藏它的隱藏功能)

前綴

在Objective-C應(yīng)用中的所有類名都必須是全局唯一的。由于很多不同的框架中會(huì)有一些相似的功能,所以在名字上也可能會(huì)有重復(fù)(users, views, requests / responses 等等),所以蘋果官方文檔規(guī)定類名需要有2-3個(gè)字母作為前綴。

類前綴

蘋果官方建議兩個(gè)字母作為前綴的類名是為官方的庫(kù)和框架準(zhǔn)備的,而對(duì)于作為第三方開發(fā)者的我們,官方建議使用3個(gè)或者更多的字母作為前綴去命名我們的類。

一個(gè)資深的Mac或iOS開發(fā)者可能會(huì)記得下面大部分的縮寫標(biāo)識(shí)符:

Prefix Frameworks
AB AddressBook / AddressBookUI
AC Accounts
AD iAd
AL AssetsLibrary
AU AudioUnit
AV AVFoundation
CA CoreAnimation
CB CoreBluetooth
CF CoreFoundation / CFNetwork
CG CoreGraphics / QuartzCore / ImageIO
CI CoreImage
CL CoreLocation
CM CoreMedia / CoreMotion
CV CoreVideo
EA ExternalAccessory
EK EventKit / EventKitUI
GC GameController
GLK GLKit
JS JavaScriptCore
MA MediaAccessibility
MC MultipeerConnectivity
MF MessageUI
MIDI CoreMIDI
MK MapKit
MP MediaPlayer
NK NewsstandKit
NS Foundation, AppKit, CoreData
PK PassKit
QL QuickLook
SC SystemConfiguration
Se Security
SK StoreKit / SpriteKit
SL Social
SS Safari Services
TW Twitter
UI UIKit
UT MobileCoreServices

第三方類前綴

直到最近,由于CocoaPods的出現(xiàn)和大量新的iOS開發(fā)者的涌現(xiàn),開源代碼的遍布,第三方代碼在很大程度上對(duì)蘋果和其余的Objective-C開發(fā)社區(qū)來(lái)說(shuō)已經(jīng)不是問(wèn)題了。最近蘋果官方的命名指南也發(fā)生了變化,它將三個(gè)字母作為前綴的建議只是做為一個(gè)習(xí)慣做法。

正因?yàn)檫@樣,那些已經(jīng)存在的第三方庫(kù)依然使用2個(gè)字母作為前綴,你可以參考一些那些在GitHub上得到很多start的Objective-C的倉(cāng)庫(kù)。

Prefix Frameworks
AF AFNetworking (“Alamofire”)
RK RestKit
PU GPUImage
SD SDWebImage
MB MBProgressHUD
FB Facebook SDK
FM FMDB (“Flying Meat”)
JK JSONKit
UI FlatUI
NI Nimbus
AC Reactive Cocoa

我們已經(jīng)看到這個(gè)第三方庫(kù)的前綴已經(jīng)和我的AFNetworking一樣了,所以最好還是要在你的代碼中遵守要三個(gè)字母以上的作為類前綴的規(guī)定(https://github.com/AshFurrow/AFTabledCollectionView)。

對(duì)于那些針對(duì)特殊功能而寫的第三方庫(kù)的作者,可以考慮在下一次主要升級(jí)時(shí)使用@compatibility_alias來(lái)為那些使用者們提供一個(gè)天衣無(wú)縫的轉(zhuǎn)移路徑。

方法前綴

不僅是類容易造成命名沖突,selectors也很容易造成命名沖突,甚至方法比類會(huì)有更多的問(wèn)題。
考慮一下這個(gè)category:

  1. @interface NSString (PigLatin) 
  2. - (NSString *)pigLatinString; 
  3. @end 

如果 -pigLatinString方法被另一個(gè)category實(shí)現(xiàn)了(或者以后版本的iOS或者M(jìn)ac OS X 在NSString類中也添加了同樣名字的方法),那么調(diào)用這個(gè)方法就會(huì)得到未定義的行為錯(cuò)誤,因?yàn)槲覀儾荒鼙WC在runtime中哪個(gè)方法會(huì)先被定義。

我們可以通過(guò)在方法名前加前綴來(lái)避免這個(gè)問(wèn)題,就像加這個(gè)類名一樣(在類別名前加前綴也是個(gè)好辦法):

  1. @interface NSString (XXXPigLatin) 
  2. - (NSString *)xxx_pigLatinString; 
  3. @end 

蘋果官方建議所有category方法使使用前綴,這個(gè)建議比類名需要加前綴的規(guī)定更加廣為人知和接受。

很多開發(fā)者都在熱情地討論著這個(gè)規(guī)定的某一方面。然而,無(wú)論是通過(guò)成本角度還是效益角度來(lái)衡量命名沖突風(fēng)險(xiǎn)的可能性都是是不全面的:

category的主要功能是通過(guò)語(yǔ)法糖將一些有用的功能包裹進(jìn)原來(lái)的類中。任何一個(gè)category方法都可以被選擇性實(shí)現(xiàn),你也可以把他當(dāng)做是self的一個(gè)隱型的功能方法。

當(dāng)我在編譯器的環(huán)境參數(shù)中將OBJC_PRINT_REPLACED_METHODS這個(gè)參數(shù)設(shè)置為YES,那我們就能在編譯的時(shí)候檢測(cè)方法名是否有沖突。實(shí)際上,方法名的沖突是很少發(fā)生的,而且在發(fā)生的時(shí)候,他們通常會(huì)得到一個(gè)needlessly duplicated across dependencies的提示。即使發(fā)生最壞的情況,程序在運(yùn)行是出現(xiàn)異常,那么很可能是兩個(gè)方法名一樣,那么他們做的事情也是一樣的,所以結(jié)果也不會(huì)有什么變化。就像Swiss Army Knife寫了一個(gè)category,他定義了NSArray中的-firstObject這個(gè)方法,那么只要蘋果官方?jīng)]有在NSArray中加這個(gè)方法的話,那么這個(gè)類別方法一直有效的。

在蘋果官方的編程指南有很多嚴(yán)肅又松散的解釋。這里沒(méi)有固定的文檔,他們可能一直變化。看到這里,如果你還是懸而未決,那么你只需要把的category方法名加上前綴,如果你還是選擇不去做任何改變,那么你就等著自食其果吧。

Swizzling

在Swizzling時(shí),方法名加前綴或者后綴也是非常有必要的,這個(gè)我在上周關(guān)于swizzling的文章中提到過(guò)。

  1. @implementation UIViewController (Swizzling) 
  2.   
  3. @implementation UIViewController (Swizzling) 
  4.   
  5. - (void)xxx_viewDidLoad { 
  6.     [self xxx_viewDidLoad]; 
  7.   
  8.     // Swizzled implementation 

我們真的需要命名空間么?

在最近關(guān)于Objective-C替換、改造和重塑的討論中,我可以明顯地發(fā)現(xiàn)命名空間是未來(lái)的一個(gè)趨勢(shì)。但是它到底給我們帶來(lái)了什么呢?

美學(xué)?除了IETE成員和軍事人員,我想沒(méi)有人會(huì)喜歡CLAs的視覺(jué)審美,但是用::,/或者另外的.這些符號(hào)真的能讓我們覺(jué)得更好么?你真的想要以后把NSArray叫做Foundation Array?(那我這個(gè)NSHipster.com這個(gè)博客不是也得改名字了?!)

語(yǔ)義學(xué)?我比較一下其他的語(yǔ)言,看看他們是怎么用命名空間的,那么你就會(huì)意識(shí)到命名空間不能解決所有不明確的問(wèn)題??赡茉谀承╊~外環(huán)境的情況下,那些命名空間會(huì)出現(xiàn)更多問(wèn)題。

你還是不贊同,那么你想象一下Objective-C的命名空間的實(shí)現(xiàn)可能會(huì)像這個(gè)樣子,你會(huì)覺(jué)得怎么樣:

  1. @namespaceX 
  2.     @implementation Obje 
  3.     @using F: Foundatio 
  4.     - (void)fo 
  5.       F:Array *array = @[<a href="http://www.jobbole.com/members/1/" rel="nofollow">@1</a>,@2, @3 
  6.       // 
  7.      
  8.     @en 
  9. @end 

雖然Objective-C有繁瑣的代碼但也有容易理解的明顯優(yōu)點(diǎn)。我們作為開發(fā)者去討論NSString的時(shí)候,我們不會(huì)把它理解成別的意思,編 譯器也是一樣。當(dāng)我們?cè)陂喿x代碼時(shí),我們不需要過(guò)多地去考慮這些代碼是什么作用的。并且最重要的是,這個(gè)類名在google這些搜索引擎中很容易就可以找到。

不管怎樣,如果你對(duì)這個(gè)討論感興趣的話,我強(qiáng)烈建議你看一下Kyle Sluder《 this namespace feature proposal 》。非常值得一看。

責(zé)任編輯:閆佳明 來(lái)源: blog.jobbole
相關(guān)推薦

2011-05-11 11:20:26

Objective-C

2011-07-29 16:16:30

Objective-c block

2011-08-17 10:58:59

Objective-C構(gòu)造函數(shù)

2011-08-17 10:29:39

Objective-C預(yù)處理

2011-07-18 16:36:51

Objective-C XCode

2015-10-08 10:01:10

Objective-CLayout

2014-04-01 10:50:42

iOS開發(fā)runtimeObjective-C

2011-08-04 10:57:33

Objective-C C語(yǔ)言 BOOL

2011-08-04 13:38:01

Objective-C C++

2011-08-16 10:23:04

Objective-CNSAutoreleaXcode常用鍵

2011-07-08 18:44:09

Objective-C Self Super

2011-08-16 13:43:40

Objective-C文件cocoa

2011-08-15 14:32:42

Objective-C委托協(xié)議

2011-07-27 16:55:12

Objective-c 閉包

2011-08-01 17:11:43

Objective-C 函數(shù)

2011-08-17 11:05:22

Objective-C方法

2011-08-18 09:21:17

Objective-C

2011-07-29 15:47:21

iPhone開發(fā) Objective- C

2014-08-05 13:09:34

Objective-C動(dòng)態(tài)特性

2011-08-04 10:04:17

Objective-C 分類 協(xié)議
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)