無意間看到自己以前學習swift的筆記,從近兩年蘋果的發布會,可以看出蘋果推動swift的決心,OC更換為swift也是未來發展的趨勢,想起當初自己鉆研學習swift的痛苦的情景,現在把它們整理出來并與現在最新的swift結合以供初學者使用,讓初學者少走彎路。有時間會陸續整理后面知識的學習筆記。
第一個 swift 項目
新建 swift 項目步驟和 oc 相同,只需要在建項目時,選擇編程語言為 swift
打開 ViewController.swift 文件,鍵入以下代碼,點擊運行,執行我們的第一個單頁面的 swift 項目。
//
import UIKit
//類的聲明和實現,寫在一個 .swift 文件里面
//用點語法替代了 oc 的 []語法
//對變量常量的定義取消了指針
//swfit 可以直接調用的 oc 的 Foundation 框架和 UIKit 框架的 api
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//相當于 oc 的 [[UIView alloc] initWithFrame: CGRectMake(0, 20, 200, 200)]
let subView = UIView(frame: CGRect(x: 0, y: 20, width: 200, height: 200))
subView.backgroundColor = UIColor.blueColor()
view.addSubview(subView)
let button = UIButton(type: .Custom)
button.frame = CGRect(x: 10, y: 10, width: 50, height: 30)
button.backgroundColor = UIColor.purpleColor()
subView.addSubview(button)
button.addTarget(self, action: "buttonClick", forControlEvents: UIControlEvents.TouchUpInside)
}
func buttonClick() {
print("hello, world!")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
總結
- 在 Swift 中沒有了 main.m,@UIApplicationMain 是程序入口
- 在 Swift 中只有 .swift 文件,沒有 .h/.m 文件的區分
- 在 Swift 中,一個類就是用一對 {} 括起的,沒有 @implementation 和 @end
- 每個語句的末尾沒有分號,在其他語言中,分號是用來區分不同語句的
- 在 Swift 中,一般都是一行一句代碼,因此不用使用分號
與 OC 的語法快速對比
- 在 OC 中 alloc / init 對應 ()
- 在 OC 中 alloc / initWithXXX 對應 (XXX: )
- 在 OC 中的類函數調用,在 Swift 中,直接使用 .
- 在 Swift 中,絕大多數可以省略 self.,建議一般不寫,可以提高對語境的理解(閉包時會體會到)
- Swift 中,枚舉類型的前綴可以省略,如:.ContactAdd,但是:很多時候沒有智能提示
- 監聽方法,直接使用字符串引起
- 在 Swift 中使用 print() 替代 OC 中的 NSLog,效率更高!
playGround 介紹
- playGround 是 xcode6.0 之后推出的一個新功能,可以一邊寫 swfit 代碼,一邊即時結果,無需手動編譯;
- playGround 是一款不錯的 swfit 學習工具,如果開發項目,仍然需要新建項目。
- 由于playGround是即時編譯,所以容易報錯(電腦配置過低也容易報錯),如果確認語法沒錯 ,需要重行啟動playGround
基本語法
常量和變量
定義
- let 定義常量,一經賦值不允許再修改
- var 定義變量,賦值之后仍然可以修改
// 定義常量 let / 變量 var
// 格式: let/var 變量名: 類型 = 值
// 提示: Swift 提供了自動推導,如果使用默認的數據類型,: 數據類型
可以省略
// 格式: let/var 變量名 = 值,變量類型會根據右側的結果自動推導
// 定義常量并且直接設置數值
let x: Int = 10
// 常量數值一經設置,不能修改,以下代碼會報錯
// x = 30
// 使用 : 類型
,僅僅只定義類型,而沒有設置數值
let y: Int
// 常量有一次設置數值的機會,以下代碼沒有問題,因為 y
還沒有被設置數值
y = 10
// 一旦設置了數值之后,則不能再次修改,以下代碼會報錯,因為 y
已經被設置了數值
// y = 50
print(x + y)
// 變量設置數值之后,可以繼續修改數值
var z: Int
z = 100
z = 200
print(x + y + z)
類型自動推導
Swift能夠根據右邊的代碼,推導出變量的準確類型
通常在開發時,不強制要求指定變量的類型,如果需要指定,可以在變量名后使用:,然后跟上變量的類型
重要技巧:Option + Click 可以查看變量的類型
沒有隱式轉換
Swift 對數據類型要求異常嚴格。在任何時候,都不會做隱式轉換,如果要對不同類型的數據進行計算,必須要顯式的轉換。
let x = 100 //swfit 會自動推導 x 為整型
let y = 10.5 //swfit 會自動推導 y 為浮點型
let num = Double(x) + y
let num1 = x + Int(y)
let 和 var 的選擇
應該盡量先選擇常量,只有在必須修改時,才需要修改為 var
- 在 Xcode 7.0 中,如果沒有修改變量,Xcode 會提示修改為 let
可選值
可選值(Optional) 是 Swift 的一大特色,也是 Swift 初學者最容易困惑(痛不欲生)的問題
所謂可選值(optional),就是指一個變量或常量,可能有值,也可能沒有值。
場景舉例:用一個值保存網絡請求的數據;如果請求成功,則有值;如果請求失敗,就沒有值。
可選值的定義
定義常量/變量時,在類型后面加一個?表示該變量是可選的。
可選值必須提定類型
定義一個可選變量時,表示該變量可以有一個指定類型的值,也可以是 nil;變量可選項的默認值是 nil
常量可選項沒有默認值,主要用于在構造函數中給常量設置初始數值
let x: Optional = 10
let y: Optional<Int>
let a: Int? //a默認沒有值
var b: String? //b的默認值為 nil
let aa: Int? = 10 //aa
let bb: String? = "hello, world"
- 可選值解包
如果 Optional 值是 nil,不允許參與計算, 只有解包(unwrap)后才能參與計算
?告訴編譯器:我是一個可選值,不要拿我做運算
!告訴編譯器:我一定有值,快來使用我吧!一旦編譯器解包后發現沒有值,就會崩潰(比如說你女朋友過生日,你送給她一個iPhone10的盒子,她興奮的打開,發現里面是空的,那就會生氣發火)
如果不確定可選值是否有值,使用前,需要判斷是否為nil
注意:必須要確保解包后的值不是 nil,否則會報錯
- 常見錯誤
unexpectedly found nil while unwrapping an Optional value 翻譯 在對可選項[解包]時發現 nil
可選綁定
由于可選項的內容可能為 nil,而一旦為 nil 則不允許參與計算。因此在實際開發中,經常需要判斷可選項的內容是否為 nil
單個可選項判斷
let url = NSURL(string: "http://www.baidu.com")
//: 方法1: 強行解包 - 缺陷,如果 url 為空,運行時會崩潰
let request = NSURLRequest(URL: url!)
//: 方法2: 首先判斷 - 代碼中仍然需要使用 !
強行解包
if url != nil {
let request = NSURLRequest(URL: url!)
}
//: 方法3: 使用 if let
,這種方式,表明一旦進入 if 分支,u 就不在是可選項
if let u = url where u.host == "www.baidu.com" {
let request = NSURLRequest(URL: u)
}
可選項條件判斷
//: 1> 初學 swift 一不小心就會讓 if 的嵌套層次很深,讓代碼變得很丑陋
if let u = url {
if u.host == "www.baidu.com" {
let request = NSURLRequest(URL: u)
}
}
>//: 2> 使用 where 關鍵字,
if let u = url where u.host == "www.baidu.com" {
let request = NSURLRequest(URL: u)
}
小結: if let 不能與使用 &&、|| 等條件判斷 如果要增加條件,可以使用 where 子句 注意:where 子句沒有智能提示
多個可選項判斷
- 可以使用
,
同時判斷多個可選項是否為空
let oName: String? = "張三"
let oNo: Int? = 100
if let name = oName {
if let no = oNo {
print("姓名:" + name + " 學號: " + String(no))
}
}
if let name = oName, let no = oNo {
print("姓名:" + name + " 學號: " + String(no))
}
判斷之后對變量需要修改
let oName: String? = "張三"
let oNum: Int? = 18
if var name = oName, num = oNum {
name = "李四"
num = 1
print(name, num)
}
guard
guard 是與 if let 相反的語法,Swift 2.0 推出的
let oName: String? = "張三"
let oNum: Int? = 18
guard let name = oName else {
print("name 為空")
return
}
guard let num = oNum else {
print("num 為空")
return
}
// 代碼執行至此,name & num 都是有值的
print(name)
print(num)
在程序編寫時,條件檢測之后的代碼相對是比較復雜的,在判斷的層次比較多的時候,使用 guard,減少嵌套的層次
if條件判斷
Swift 中沒有 C 語言中的非零即真概念
在邏輯判斷時必須顯示地指明具體的判斷條件 true / false
if 語句條件的 () 可以省略
但是 {} 不能省略
let num = 200
if num < 10 {
print("比 10 小")
} else if num > 100 {
print("比 100 大")
} else {
print("10 ~ 100 之間的數字")
}
三目運算
Swift 中的 三目 運算保持了和 OC 一致的風格
x > 20 ? print("大了") : print("小了")
/**
'( )' 表示執行
*/
x > 20 ? print("真的大了") : ()
適當地運用三目,能夠讓代碼寫得更加簡潔
判斷可選值是否為 nil
讓變量/常量強行解包參與運算會有風險,如果沒有值,則會崩潰,所以在使用可選值時,最好先判斷 可選值是否為 nil
var a: Int? = 10
var b = 10
if a != nil {
print("有值為\(a!+b)")
}else{
print("沒有值")
}
?? 空合運算符
?? 運算符可以用于判斷 變量/常量 的數值是否是 nil,如果是則使用后面的值替代
在使用 Swift 開發時,?? 能夠簡化代碼的編寫
var a: Int? = 10
var b = 10
if (a ! = nil) {
a = 0
}
let c = a + b
let d = (a ?? 0) + b
//注意:?? 的優先級低,在使用時,應該注意使用 ()
var str: String? = "小明"
// 注意 `??` 的優先級低,在使用時,應該注意使用 `()`
print((str ?? "無名") + " 你好")
print(str ?? "無名" + " 你好")
switch
switch 不再局限于整數
switch 可以針對任意數據類型進行判斷
不再需要 break
每一個 case后面必須有可以執行的語句
要保證處理所有可能的情況,不然編譯器直接報錯,不處理的條件可以放在 default 分支中
每一個 case 中定義的變量僅在當前 case 中有效,而 OC 中需要使用 {}
let score = "優"
switch score {
case "優":
let name = "學生"
print(name + "80~100分")
case "良": print("70~80分")
case "中": print("60~70分")
case "差": print("不及格")
default: break
}
- 也可以作條件判斷
var score = 80
switch score {
case let x where x < 60:
print("不及格")
case let x where x >= 60 && x < 70:
print("及格")
case let x where x >= 70 && x < 80:
print("良好")
case let x where x >= 80 && x < 90:
print("優秀")
case let x where x >= 90 && x <= 100:
print("牛逼")
default:
print("超過數值")
}
- 注意
如果條件沒有覆蓋所有的值,需要加default
for 循環
OC 風格的循環
var sum = 0
for var i = 0; i < 10; i++ {
sum += i
}
print(sum)
swift 風格的循環
- 0...10表示閉區間,數學中的[0,10]
- 0..<10表示開區間[0,10)
var sum = 0
//for-in,0..<10, 表示從0到9
for i in 0..<10 {
sum += i
}
for j in (0..10).reverse() {
print(j)
}
print(sum)
//范圍 0...10 表示從0到10
sum = 0
for i in 0...10 {
sum += i
}
print(sum)
注意:..< 和 ... 用于定義 Range 類型,左右都不要添加空格
格式: for 變量 in 范圍 { // 代碼 }
省略下標,符號 '_'
for _ in 0...10 {
print("hello")
}