天天看點

Swift要點:從Objective-C開發者的角度看Swift

代碼環境是xcode6.3-beta3.

swift已經極大的改變了開發ios應用的方式。本文中,我會列出swift的幾個重點,并且和objective-c一一做出對比。

注意,本文不是swift的入門指導。蘋果釋出了swift programming language,強烈建議您讀一讀這本書。文本主要介紹swift中比較酷炫的特性。

swift提供的第一個重大的改進是類型推斷。使用了類型推斷的程式設計語言,開發者不需要在聲明中明确指定變量的類型。編譯器會自動探知要賦給變量的值的類型。比如下面的例子,編譯器會自動設定變量的類型為string:

和類型推斷一起帶來的是類型安全。在swift中,編譯器(一般來說全部,但是在很少的情況下)知道一個類型的全部類型。這樣給編譯器一個選擇如何編譯代碼的機會,因為編譯器有足夠的資訊。

這承托出了objective-c的一個非常動态的本質。在objective-c中,任何類型在編譯期間都是未知的。這也是為什麼你可以在運作時給已經存在的類添加方法,添加一個全新的類型,甚至于改變一個對象的類型。

看看objective-c的代碼:

當編譯器看到對方法sayhello的調用的時候,它就會檢查類型person類的頭檔案中是否有一個叫做sayhello的方法。如果沒有就報錯。編譯器就隻可以做這些。這确實可以你可能引入的最初簡單的bug:如拼寫錯誤。但是,因為動态性,編譯器不可能知道sayhello方法是否會在運作改變、甚至是否存在。這可能是一個協定中得optional方法。比如(還記得那些使用respondstoselector的檢查嗎)。

由于缺乏強類型, 在objective-c中調用方法的時候編譯器幾乎不能做什麼優化。處理代碼動态分發的方法是:objc_msgsend。我确定你在很多的時候見過這個方法。在這個方法中,尋找selector并調用。你不能說這沒有增加複雜度。

再回頭看看swift的實作:

swift的編譯器也非常的有用。可以排除細微的類型相關的bug。它也能使你的代碼運作的更快。

比如,你希望把一對值存放在一起。你可以用swift實作存放整型數值的結構:

Swift要點:從Objective-C開發者的角度看Swift
Swift要點:從Objective-C開發者的角度看Swift

sort of useful. but now you want this to work for floating point numbers as well. you could define a<code>floatpair</code> class, but that would look awfully similar. this is where generics come in. instead of declaring a whole new class, you could simply do this:

有點用處,但是你也想讓這個可以用于浮點數。你可以定義一個floatpair類, 但是實在是太相似了。這個時候泛型就會發揮用處了。相對于定義一個全新的類型,你可以這樣:

Swift要點:從Objective-C開發者的角度看Swift
Swift要點:從Objective-C開發者的角度看Swift
請各位讀者原諒我用了這麼爛得命名方式啊。。。

非常有用!你可能不是很清楚你為什麼需要泛型,但是相信我會有很多時候你會用到。你很快會發現在哪裡可以使用這些代碼。

也許你覺得nsarray和nsdictionary和對應的可變類型都已經很好用了。但是你需要學習對應的swift容器。幸運的是,他們非常相似。如:

這些對你來說已經非常熟悉了。瞅一眼就可以搞定的。在objective-c中,數組和字典可hi包含你想要的任何類型。但是在swift中數組和字典是強類型的。而且這些容器都是泛型類型的。

上面的兩個變量可以使用類型表達式來重寫(你不是必須要這麼做),比如:

notice how generics are used to define what can be stored in the container. there is also a short form for these, which is slightly more readable, but essentially boils down to the same thing:

注意泛型是怎麼定義什麼可以放進容器中的。定義的方式也有簡短的方式的,可讀性更好。但是本質上來說是一樣的:

注意,這個時候你無法給數組添加任何的不是int類型的值。這看起來不好,但是非常有用。你不再需要在文檔中專門指明屬性傳回的數組中存放的是什麼類型的值。編譯器會自動檢測錯誤并優化代碼的編譯。

swift容器的一個有意思的地方是他們都是可變的(mutable)。array和dictionary沒有“mutable”的對應類型了。可變和不可變都由let和var關鍵字控制。let就是用來聲明一個常量的關鍵字,var是用來聲明一個變量的。let就像是c、c++或者objective-c中得const關鍵字一樣。

the way this relates to collections is that collections declared using <code>let</code> cannot change size. that is, they cannot be appended to, or removed from. if you try to, then you get an error like so:

使用let聲明的集合不能再修改size,也就是不能再append或者remove。如果你這麼做了,就會報錯:

字典也同樣使用這個規則。這允許編譯器推測出這一類型的集合并作出相應的優化。如果size不能修改,集合的存儲實作不再需要重新配置設定新的空間容納新的值。是以,經常使用let來定義不再改變的集合是一個很好的實踐。

objective-c的字元串非常難用。即使是簡單的拼接字元串之類的都需要寫很多的代碼。比如:

Swift要點:從Objective-C開發者的角度看Swift
Swift要點:從Objective-C開發者的角度看Swift

this is quite tedious and contains a lot of characters that are nothing to do with the data being manipulated. the same in swift would look like this:

這樣的寫法非常的冗長,而且包含了與本次操作無關的其他字元。同樣的功能在swift裡看起來是這樣的:

Swift要點:從Objective-C開發者的角度看Swift
Swift要點:從Objective-C開發者的角度看Swift

非常的清晰。更加清晰的建立一個字元串,你可以使用字元串拼接操作符+=。不再需要可變字元串和非可變字元串。

另一個swift字元串的變化是”字元串的比較“。你知道在objective-c中不能使用==來比較兩個字元串的相等。你得用isequaltostring方法。這是應為==是比較的指針是否相等。swift中可以直接使用==比較兩個字元串。也就是說字元串可以在switch-case表達式中。更多相關請繼續收看下一節内容。

swift的字元串的另一個好東西是本地支援unicode。你可以使用任意的unicode字元,即使是在變量名和函數名中。如果你願意你可以聲明一個方法 (pile of poo!)。

另一個字元串的好東西是一種内建的方法計算一個字元串的長度。當字元串全部都是unicode字元的時候,計算字元串的長度就變得重要了。你不能隻是說有多少個byte用于存放utf8字元串了。因為有的字元一個byte是不夠的。在objective-c中,nsstring通過utf16的個數來計算字元串的長度,2個byte存放一個字元串。但是,有的unicode字元一次需要用兩個2個byte的組合,是以之前nsstring的計算方式不再能正确的表明字元串中字元的個數。

fortunately, swift has a handy function to calculate the true number of code-points in a string. it uses the top level function called <code>countelements()</code>. you would use it like so:

幸運的是,swift有一個很好用的方法可以計算字元串的字元個數。這需要用到一個全局的countelements()方法。使用方法:

在swift1.2中使用count方法

如你所見,swift的字元串真的是非常好用!

本文的最後需要簡單的介紹一下swift的switch表達式。swift的switch表達式對objective-c的switch表達式進行了極大的更新。因為,不打破objective-c這個c語言的超集的情況是不能有大的更新的。

the first exciting feature is switching on strings. this is something that you may have wanted to do before, but couldn’t. to “switch” on strings in objective-c you had to use lots of if-statements with<code>isequaltostring:</code> like so:

第一個就是switch表達式可以使用字元串。這也許是你早就想要的一個功能。在objective-c中你不得不使用很多的if-else表達式和isequaltostring方法,比如:

Swift要點:從Objective-C開發者的角度看Swift
Swift要點:從Objective-C開發者的角度看Swift

而在swift中就很簡單了:

Swift要點:從Objective-C開發者的角度看Swift
Swift要點:從Objective-C開發者的角度看Swift

除了在switch上使用string以外,還有一些有意思的地方。swtich表達式中是沒有break的。這是因為swift的switch表達式不再自動執行下面的一個。不再有直接執行後面的代碼的問題。

來看看新的代碼:

Swift要點:從Objective-C開發者的角度看Swift
Swift要點:從Objective-C開發者的角度看Swift

是以,不再有break的問題。

下一個有意思的地方是...和..&lt;。這些新的操作符是用來定義range的。前面的而一個是包含右邊的數字。後面的一個是不包含右邊的數字。這非常有用。

歡迎加群互相學習,共同進步。qq群:ios: 58099570 | android: 330987132 | go:217696290 | python:336880185 | 做人要厚道,轉載請注明出處!http://www.cnblogs.com/sunshine-anycall/p/4344956.html