淺析Objective-C字面量

來源:互聯網
上載者:User

標籤:

編寫Objective-C程式時,總會用到某幾個類,它們屬於Foundation架構。雖然從技術上來說,不用Foundation架構也能寫出Objective-C代碼,但實際上卻經常要用到此架構。這幾個類是NSString、NSNumber、NSArray、NSDictionary。從類名上即可看出各自所表示的資料結構。

Objective-C以文法繁雜而著稱。事實上的確是這樣。不過,從Objective-C 1.0起,有一種非常簡單的方式能建立NSString對象。這就是“字串字面量”(string literal),其文法如下:
NSString *someString = @”Effective Objective-C 2.0”;

如果不用這種文法的話,就要以常見的alloc及init方法來分配並初始化NSString對象了。在版本較新的編譯器中,也能用這種字面量文法來聲明NSNumber、NSArray、NSDictionary類的執行個體。使用字面量文法(literal syntax)可以縮減原始碼長度,使其更為易讀。

字面數值

有時需要把整數、浮點數、布爾值封入Objective-C對象中。這種情況下可以用NSNumber類,該類可處理多種類型的數值。若是不用字面量,那麼就需要按下述方式建立執行個體:
NSNumber *someNumber = [NSNumber numberWithInt:1];

上面這行代碼建立了一個數字,將其值設為整數1。然而使用字面量能令代碼更為整潔:
NSNumber *someNumber = @1;

大家可以看到,字面量文法更為精簡。不過它還有很多好處。能夠以NSNumber執行個體表示的所有資料類型都可使用該文法。例如:
NSNumber intNumber = @1;
NSNumber 
floatNumber = @2.5f;
NSNumber doubleNumber = @3.14159;
NSNumber 
boolNumber = @YES;
NSNumber *charNumber = @’a’;

字面量文法也適用於下述運算式:

 

以字面量來表示數值十分有用。這樣做可以令NSNumber對象變得整潔,因為聲明中只包含數值,而沒有多餘的文法成分。

字面量數組

數組是常用的資料結構。如果不使用字面量文法,那麼就要這樣來建立數組:

 

 

而使用字面量文法來建立則是:

 

 

上面這種做法不僅簡單,而且還利於運算元組。數組的常見操作就是取某個下標所對應的對象,這用字面量來做更為容易。如果不用字面量,那麼通常會用“objectAtIndex:”方法:

 

若使用字面量,則是:

 

這也叫做“取下標”操作(subscripting),與使用字面量文法的其他情況一樣,這種方式也更為簡潔、更易理解,而且與其他語言中依下標來訪問數組元素時所用的文法類似。

不過,用字面量文法建立數組時要注意,若數組元素對象中有nil,則會拋出異常,因為字面量文法實際上只是一種“文法糖”(syntactic sugar),其效果等於是先建立了一個數組,然後把方括弧內的所有對象都加到這個數組中。拋出的異常會是這樣:

1
2
3
4
*** Terminating app due to uncaught exception
‘NSInvalidArgumentException‘, reason: ‘***
-[__NSPlaceholderArray initWithObjects:count:]: attempt to
insert nil object from objects[0]‘

 

在改用字面量文法來建立數組時就會遇到這個問題。下面這段代碼分別以兩種文法建立數組:

1
2
3
4
5
6
7
id object1 = /* ... */;
id object2 = /* ... */;
id object3 = /* ... */;

NSArray *arrayA = [NSArray array WithObjects:
                       object1, object2, object3, nil];
NSArray *arrayB = @[object1, object2, object3];

 

大家想想:如果object1與object3都指向了有效Objective-C對象,而object2是nil,那麼會出現什麼情況呢?按字面量文法建立數組arrayB時會拋出異常。arrayA雖然能建立出來,但是其中卻只含有object1一個對象。原因在於,“arrayWithObjects:”方法會依次處理各個參數,直到發現nil為止,由於object2是nil,所以該方法會提前結束。

這個微妙的差別表明,使用字面量文法更為安全。拋出異常令應用程式終止執行,這比建立好數組之後才發現元素個數少了要好。向數組中插入nil通常說明程式有錯,而通過異常可以更快地發現這個錯誤。

字面量字典

“字典”(Dictionary)是一種映射型資料結構,可向其中添加索引值對。與數組一樣,Objective-C代碼也經常用到字典。其建立方式如下:

 

這樣寫令人困惑,因為其順序是<對象>,<鍵>,<對象>,<鍵>。這與通常理解的順序相反,我們一般認為是把“鍵”映射到“對象”。因此,這種寫法不容易讀懂。如果改用字面量文法,就清晰多了:

 

上面這種寫法更簡明,而且鍵出現在對象之前,理解起來較順暢。此範例代碼還說明了使用字面量數值的好處。字典中的對象和鍵必須都是Objective-C對象,所以不能把整數28直接放進去,而要將其封裝在NSNumber執行個體中才行。使用字面量文法很容易就能做到這一點,只需給數字前加一個@字元即可。

與數組一樣,用字面量文法建立字典時也有個問題,那就是一旦有值為nil,便會拋出異常。不過基於同樣的原因,這也是個好事。假如在建立字典時不小心用了空值對象,那麼“dictionaryWithObjectsAndKeys:”方法就會在首個nil之前停下,並拋出異常,這有助於查錯。

字典也可以像數組那樣用字面量文法訪問。按照特定鍵訪問其值的傳統做法是:

 

與之等效的字面量文法則是:

 

這樣寫也省去了冗贅的文法,令此行代碼簡單易讀。

可變數組與字典

通過取下標操作,可以訪問數組中某個下標或字典中某個鍵所對應的元素。如果數組與字典對象是可變的(mutable),那麼也能通過下標修改其中的元素值。修改可變數組與字典內容的標準做法是:

 

若換用取下標操作來寫,則是:

 

局限性

字面量文法有個小小的限制,就是除了字串以外,所建立出來的對象必須屬於Foundation架構才行。如果自訂了這些類的子類,則無法用字面量文法建立其對象。要想建立自訂子類的執行個體,必須採用“非字面量文法”(nonliteral syntax)。然而,由於NSArray、NSDictionary、NSNumber都是業已定型的“子族”(class cluster,參見第9條),因此很少有人會從其中自訂子類,真要那樣做也比較麻煩。而且一般來說,標準的實現已經很好了,無須再改動。建立字串時可以使用自訂的子類,然而必須要修改編譯器的選項才行。除非你明白這樣做的後果,否則不鼓勵使用此選項,用NSString就足夠了。

使用字面量文法建立出來的字串、數組、字典對象都是不可變的(immutable)。若想要可變版本的對象,則需複製一份:

 

 

這麼做會多調用一個方法,而且還要再建立一個對象,不過使用字面量文法所帶來的好處還是多於上述缺點的。

要點

應該使用字面量文法來建立字串、數值、數組、字典。與建立此類對象的常規方法相比,這麼做更加簡明扼要。

應該通過取下標操作來訪問數組下標或字典中的鍵所對應的元素。

 用字面量文法建立數組或字典時,若值中有nil,則會拋出異常。因此,務必確保值裡不含nil。

淺析Objective-C字面量

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.