1.常量變數
let
var
2.資料型別
- 整型,浮點型,物件型別,結構體型別(swift中大部分類改為了結構體)
- 整型
-
Int8
有符號8位整型 -
Int16
有符號16位整型 -
Int 32
有符號32位整型 -
Int 64
有符號64位整型 -
Int
與平臺有關,預設相當於OC中NSInteger -
UInt8
無符號8位整型 -
UInt16,UInt32,UInt64
-
浮點型
-
Float
32位浮點型Double
64位浮點型 -
基本運算
-
相同運算子之間才能參與運算,因為swift中沒有隱式轉換
3.邏輯分支
-
if
switch
三目運算子
等判斷語句
-
guard
運算子(守護) -
當條件表示式位true的時候跳過else語句,繼續向下執行
-
當條件表示式為false的時候進入else語句中,break,continue,return,throw等跳出
guard 條件表示式 else { // 條換語句 break } 語句組 複製程式碼
-
switch
語句 -
switch 的case之後不必須加break case不在只是Int,可以是浮點,字串,區間(0..<10,0...10)
-
一個case 可以判斷多個值,用,隔開
4.迴圈
for迴圈
- 開區間(0..<10),閉區間(0...10)
- for迴圈列印字典時可以使用元組
while
,do-while
迴圈- 使用
repeat while
迴圈代替do-while迴圈 - i++已經被棄用,使用i=i+1;
5.字串
-
String
是結構體,效能比NSString 高 -
String的長度,astring.characters.count 字串長度
-
str1 + str2 兩個字串相加
-
字串的格式化輸出
String(format: "%02d:%02d", arguments: [min, second]) 複製程式碼
-
字串的擷取 暫時先轉為NSString 進行擷取
let myStr = "www.520it.com" var subStr = (myStr as NSString).substringFromIndex(4) subStr = (myStr as NSString).substringToIndex(3) subStr = (myStr as NSString).substringWithRange(NSRange(location: 4, length: 5)) 複製程式碼
6陣列
-
Array
一個範型陣列 -
陣列宣告方法
var stuArray1:Array<String> var stuArray2: [String] 複製程式碼
-
陣列的 增- 刪- 改- 查
// 新增資料 array.append("yz") // 刪除元素 array.removeFirst() // 修改元素 array[0] = "why" // 取值 array[1] 複製程式碼
-
陣列的合併 同型別的兩個陣列可以直接相加
// 陣列合並 // 注意:只有相同型別的陣列才能合併 var array = ["why", "lmj","lnj"] var array1 = ["yz", "wsz"] var array2 = array + array1; // 不建議一個陣列中存放多種型別的資料 var array3 = [2, 3, "why"] var array4 = ["yz", 23] array3 + array4 複製程式碼
7.字典
-
Dictionary 是個範型集合
-
宣告方式
var dict1: Dictionary<Int, String> var dict2: [Int: String] 複製程式碼
-
字典的增 -刪- 改- 查
// 新增資料 dict["height"] = 1.88 dict["weight"] = 70.0 // 刪除欄位 dict.removeValueForKey("height") // 修改字典 dict["name"] = "lmj" // 查詢字典 dict["name"] 複製程式碼
-
字典的遍歷 使用元組
-
字典的合併
// 字典的合併 var dict1 = ["name" : "yz", "age" : 20] var dict2 = ["height" : 1.87, "phoneNum" : "+86 110"] // 字典不可以相加合併 for (key, value) in dict1 { dict2[key] = value } 複製程式碼
8.元組
- 是swift中特有的定義一組資料,型別可相同可不相同
// 元組:HTTP錯誤 // let array = [404, "Not Found"] // 寫法一: let error = (404, "Not Found") print(error.0) print(error.1) // 寫法二: let error = (errorCode : 404, errorInfo : "Not Found") print(error.errorCode) print(error.errorInfo) // 寫法三: let (errorCode, errorIno) = (404, "Not Found") print(errorCode) print(errorIno) 複製程式碼
9.可選型別
-
可選型別的取值,有值或者是空值
-
可選型別的使用
-
使用場景
// 該方式利用型別推導 let url = NSURL(string: "www.520it.com") // 通過url來建立request物件:在使用可選型別前要先進行判斷是否有值 // 該語法成為可選繫結(如果url有值就解包賦值給tempURL,並且執行{}) if let tempUrl = url { let request = NSURLRequest(URL: tempUrl) } 複製程式碼
10.函式
-
函式的格式
func 函式名(引數列表) -> 返回值型別 { 程式碼塊 return 返回值 } func 函式名(引數1:引數1型別,引數2:引數2型別) -> 返回值型別 { 程式碼塊 return 返回值 } 複製程式碼
-
函式 外部引數和內部引數
-
變數名前加標籤就是外部引數
-
方法重寫 子類重新呼叫父類方法是重寫,override
-
方法過載 方法名相同但是引數不同,稱為方法過載
// num1和a是外部引數的名稱 func ride(num1 num1 : Int, a num2 : Int, b num3 : Int) -> Int { return num1 * num2 * num3 } var result1 = ride(num1: 20, a: 4, b: 5) // 方法的過載:方法名稱相同,但是引數不同,可以稱之為方法的過載(瞭解) func ride(num1: Int, _ num2 :Int) -> Int { return num1 * num2 } var result2 = ride(20, 20) 複製程式碼
-
函式的預設引數
-
不傳的話有個預設值
func makecoffee(type :String = "卡布奇諾") -> String { return "製作一杯\(type)咖啡。" } 複製程式碼
-
可變引數
-
可以接受不確定數量的輸入型別引數,但必須是相同型別,在引數型別後面拼接**...** 來實現
func sum(numbers:Double...) -> Double { var total: Double = 0 for number in numbers { total += number } return total } sum(100.0, 20, 30) sum(30, 80) 複製程式碼
-
函式引用型別-指標傳遞
-
預設是值傳遞,不改變外部變數的值,如果想改變,需要傳地址
-
傳入的地址必須是變數
-
swift提供inout 關鍵字實現
11.swift中類的使用
-
定義類的時候可以沒有父類,需要父類的話大多可以使用NSObject 作為父類,非OC的NSObject
-
類的屬性 分為 儲值屬性,算值屬性,類屬性
-
儲值屬性
-
計算型屬性 不儲存實際值,提供getter 和可選的setter間接獲取或設定其他屬性,
- 一般只提供getter 方法,如果只實現了getter 方法,則為只讀屬性,可以省略get{},直接return
-
類屬性 所有的類和類的例項都有一份類屬性,如果在某一處更新後,該類屬性就會被修改
-
類屬性使用static 關鍵字修改,
-
監聽屬性的修改
-
在oc中使用set 方法監聽
-
在swift中,使用屬性觀察者監聽和相應屬性值的變化
-
使用屬性的will set 方法監測新值,在didset中監測舊值
-
willSet (new){ }
didSet(old){}
-
在didset中生成計算型屬性的值
-
didSet 屬性直接賦值不會呼叫didSet方法,而是在初始化之後再賦值才能呼叫
var expires_in: NSTimeInterval = 0 { didSet { expiresDate = NSDate(timeIntervalSinceNow: expires_in) } } 複製程式碼
12.類的建構函式
-
建構函式的基本使用
-
類的屬性必須有值,如果不是在初始化的時候複製,在構造方法中給類屬性賦值,
class Person: NSObject { var name : String var age : Int // 重寫了NSObject(父類)的構造方法 override init() { name = "" age = 0 } } // 建立一個Person物件 let p = Person() 複製程式碼
-
初始化的時候給屬性賦值
-
如果在自定義物件的時候給屬性賦值,自定義init方法,會覆蓋init方法,不會有預設的初始化方法
class Person: NSObject { var name : String var age : Int // 自定義建構函式,會覆蓋init()函式 init(name : String, age : Int) { self.name = name self.age = age } } // 建立一個Person物件 let p = Person(name: "why", age: 18) 複製程式碼
13 字典轉模型 (初始化時傳入字典)
- 字典取值是NSObject 是任意型別
- 可以通過as轉換之後再賦值,不同型別不能直接賦值
class Person: NSObject { var name : String var age : Int // 自定義建構函式,會覆蓋init()函式 init(dict : [String : NSObject]) { name = dict["name"] as! String age = dict["age"] as! Int } } // 建立一個Person物件 let dict = ["name" : "why", "age" : 18] let p = Person(dict: dict) 複製程式碼
14 字典轉模型 (KVC 轉化)
- kvc 不能保證全部複製,所以屬性要有預設值,基本資料型別預設值是0,物件結構體定義為可選即可
class Person: NSObject { // 結構體或者類的型別,必須是可選型別.因為不能保證一定會賦值 var name : String? // 基本資料型別不能是可選型別,否則KVC無法轉化 var age : Int = 0 // 自定義建構函式,會覆蓋init()函式 init(dict : [String : NSObject]) { // 必須先初始化物件 super.init() // 呼叫物件的KVC方法字典轉模型 setValuesForKeysWithDictionary(dict) } } // 建立一個Person物件 let dict = ["name" : "why", "age" : 18] let p = Person(dict: dict) 複製程式碼
15閉包的介紹
-
閉包就是匿名函式
-
block
的寫法型別: 返回值(^block的名稱)(block的引數列表) ------ 值: ^(引數列表){ // 執行的程式碼 } 複製程式碼
-
swift的寫法
-
定義網路請求的類
func loadRequest(callBack:()->()){ callBack() } 複製程式碼
-
使用閉包
httpTool.loadRequest( { ( )->( ) in tableView.reloadData }) 複製程式碼
-
閉包總結
閉包的寫法: 型別: (型參列表)->( 返回值 ) 值: { ( 型參列表 ) -> 返回值型別 in // 執行程式碼 } 複製程式碼
-
尾隨閉包
-
如果閉包沒有引數沒有返回值,
( ) -> ( ) in
可以省略 -
如果閉包是作為函式的最後一個引數,則可以將閉包寫在()後面
-
如果函式只有一個引數,且最後一個引數是閉包,那麼()也可以不寫,直接在方法名後面拼接{}
省略前 httpTool.loadRequest({ ( ) -> ( ) in print(完全不省略) }) 省略1 httpTool.loadRequest({ print(省略括號 in) }) 省略2 httpTool.loadRequest( ){ print(小括號前置) } 省略3 httpTool.loadRequest{ print(終結版尾隨閉包) } 複製程式碼
-
16.閉包的迴圈引用
-
deinit{}
實現deinit 函式,檢測一個物件是否銷燬 -
swift 迴圈引用的三種方式
- 使用
weak
,使用【weak self】
,使用unowned
關鍵字
- 使用
-
使用weak
關鍵字對控制器持有,weakself是可選型別,使用時強行解包,因為一定有值weak var weakSelf = self httpTool.loadData { print("載入資料完成,更新介面:", NSThread.currentThread()) weakSelf!.view.backgroundColor = UIColor.redColor() } 複製程式碼
-
使用 【weak self】
【weak self 】寫在閉包中,在閉包中使用的self 都是weak的httpTool.loadData {[weak self] () -> () in print("載入資料完成,更新介面:", NSThread.currentThread()) self!.view.backgroundColor = UIColor.redColor() } 複製程式碼
-
unowned 類似oc的unretain
,即使原來引用的物件釋放了,也會對釋放的物件,持有一個無效的引用,不是可選的,不可能指向nilhttpTool.loadData {[unowned self] () -> () in print("載入資料完成,更新介面:", NSThread.currentThread()) self.view.backgroundColor = UIColor.redColor() } 複製程式碼
17.懶載入
-
希望所有的物件,只有載入的時候才能加入到記憶體中,
-
lazy
關鍵字,是專門修飾懶載入屬性的 -
格式
lazy var 變數名 = { 建立變數程式碼 }() 複製程式碼
-
使用
// 懶載入的本質是,在第一次使用的時候執行閉包,將閉包的返回值賦值給屬性 // lazy的作用是隻會賦值一次 lazy var array : [String] = { () -> [String] in return ["why", "lmj", "lnj"] }() 複製程式碼
18.便利建構函式
-
convenience : 便利,使用convenience修飾的建構函式叫做便利建構函式
-
便利建構函式通常用在對系統的類進行建構函式的擴充時使用
-
便利建構函式的特點
-
便利建構函式,一般寫在extension中
-
便利建構函式,在init前面新增convenience 關鍵字
-
在便利構造器中需要明確呼叫
self.init()
, 而且是先呼叫。 -
在繼承中,重寫父類的方法中,初始化自己的方法中,先初始化自己的屬性,之後呼叫父類的super.init()
19 #Selector()
事件監聽
-
事件監聽本質傳送訊息.但是傳送訊息是OC的特性
-
將方法包裝成@SEL --> 類中查詢方法列表 --> 根據@SEL找到imp指標(函式指標) --> 執行函式
-
如果swift中將一個函式宣告稱private,那麼該函式不會被新增到方法列表中
-
如果在private前面加上@objc,那麼該方法依然會被新增到方法列表中
20.型別轉換
-
型別轉換在 Swift 中使用
is
和as
操作符實現 ,你也可以用它來檢查一個型別是否實現了某個協議,就像在檢驗協議的一致性部分講述的一樣。 -
定一個類
MediaItem
,name 屬性,init(name:) 方法 -
其2個子類
Movie
,Song
-
檢查型別
-
is
判斷是一個例項,是否屬於特定子類 if item is Movie -
向下轉型
-
使用子類特有的屬性和方法,使用
as
轉化為子類 as?和as!
21.Any 和 AnyObject
的型別轉換
- Any 表示任何型別,包括函式型別
- AnyObject表示任何型別的例項
for thing in things { switch thing { case 0 as Int: print("zero as an Int") case 0 as Double: print("zero as a Double") case let someInt as Int: print("an integer value of \(someInt)") case let someDouble as Double where someDouble > 0: print("a positive double value of \(someDouble)") case is Double: print("some other double value that I don't want to print") case let someString as String: print("a string value of \"\(someString)\"") case let (x, y) as (Double, Double): print("an (x, y) point at \(x), \(y)") case let movie as Movie: print("a movie called '\(movie.name)', dir. \(movie.director)") case let stringConverter as String -> String: print(stringConverter("Michael")) default: print("something else") } } // zero as an Int // zero as a Double // an integer value of 42 // a positive double value of 3.14159 // a string value of "hello" // an (x, y) point at 3.0, 5.0 // a movie called 'Ghostbusters', dir. Ivan Reitman // Hello, Michael 複製程式碼
22.在一個型別中巢狀另外一個型別
-
BlackjackCard
(二十一點),結構體中,巢狀Suit
,Rank
兩個列舉struct BlackjackCard { // 巢狀的 Suit 列舉 enum Suit: Character { case Spades = "♠", Hearts = "♡", Diamonds = "♢", Clubs = "♣" } // 巢狀的 Rank 列舉 enum Rank: Int { case Two = 2, Three, Four, Five, Six, Seven, Eight, Nine, Ten case Jack, Queen, King, Ace struct Values { let first: Int, second: Int? } var values: Values { switch self { case .Ace: return Values(first: 1, second: 11) case .Jack, .Queen, .King: return Values(first: 10, second: nil) default: return Values(first: self.rawValue, second: nil) } } } // BlackjackCard 的屬性和方法 let rank: Rank, suit: Suit var description: String { var output = "suit is \(suit.rawValue)," output += " value is \(rank.values.first)" if let second = rank.values.second { output += " or \(second)" } return output } } 複製程式碼
-
初始化
let theAceOfSpades = BlackjackCard(rank: .Ace, suit: .Spades)
-
使用:
let heartsSymbol = BlackjackCard.Suit.Hearts.rawValue