(一)簡介程序員
(1)優於OC,快速,安全json
(2)取消了預編譯指令包括宏定義(OC用的太多了)swift
(3)取消了OC指針和不安全訪問的使用(看不到星星了)api
(4)所有點語法數組
(5)3.0中對Foundation框架作了不少改變,去除了NS,將絕大部分class轉換成struct結構體(爲了考慮性能和安全性,絕大部分使用結構體來代替之前的類,可是在實際使用感受不到)安全
(6)之前是OC調UIKit,如今就是Swift調UIKit,這點事沒問題的閉包
(7)swift由於語法的嚴謹性可讓不少錯誤提早遇到,這樣不多出現bug讓程序停在main致使沒法找到app
(8)@UIApplicationMain是程序的入口框架
(9)只有.h沒有.m異步
(10)全部的代碼都包括在{}裏,默認方法func都有縮進!
(11)語法的allocinit替換成()
(二)PlayGround
(1)能夠看蘋果官方自帶的tips和100個tips,都在Placground來使用
(三)基礎
(1)不適用self. 在閉包或者編譯器提示的時候再使用
(2)分號是用來分割語句的,若是一行洗不少,就能夠加分號,通常時候能夠不加
(3)#function打印執行的函數
(4)添加標記用到// MARK: - 選擇,若是是接下來要作的能夠用// TODO:和// FIXME:這些很是有用
(四)變量和常量
(1)let:常量,若是從沒被修改過,那就用let,不可變的更安全,因此儘可能使用let,須要變化時候改var
(2)var:變量
(3)能夠自動推導類型(Option + Click)整數默認Int,小數默認Double
(4)Swift對類型要求異常嚴格,任何不一樣類型的數據不能直接運算(哪怕是Int和Double),不會作一些自動的轉換來轉換成Double。Swift不存在基本數據類型,Int和Double都是結構體其實,強轉用Double(x)完成,或者在定義的時候直接指定變量的類型let x : Double = 10;(不多使用)
(五)可選項(Optional)
(1)定義變量時,若是是可選的,表示能夠有值,也能夠是nil,用「?」
(2)強行解包 「!」,程序員來注意!,而且要少用,可能會崩
(3)最多見的錯誤:解包的時候發現nil。fatal error: unexpectedly found nil while unwrapping an Optional value
(4)let可選的話,沒有默認值,須要賦值。var可選的話,默認值爲nil
(5)可選項在參與計算時候必須解包
(六)邏輯分支(if)
(1)三目運算符:Int(x!) > 5 ? print("dayu5") : print("xiaoyu5") 或者 Int(x!) > 5 ? print("dayu5") : () 這樣就對後面的不做處理。()表示空執行。
(七)不強行解包的方法
(1)強行解包的寫法:"??"一個簡單的三目,這樣無需作不少判斷,是否是xy都不得0了。注意?? 必須加個(),由於??操做符號的優先級低,是最後判斷的,因此不加()可能後面的都當作判斷不執行了。??寫法不須要解包了
func demo(x: Int? , y : Int?) {
print( (x ?? 0) + (y ?? 0) )
}
(2)if let的寫法:iflet/ifvar連用就能夠進行判斷,這個let的x1和y1做用於只在循環裏,iflet/var也不須要解包了
if let x1 = x , let y1 = y {
print(x1 + y1)
}
(3)guard let else的寫法:和iflet相反,else裏面通常是沒值return,以後才執行須要的代碼。guard能夠下降分支層次,若是要執行的代碼不少,原本在if裏執行,{}就多了一層,若是用guard守衛必定有值才執行,這樣層次就少了一層。guardLet很重要,也能夠省略不少解包
guard let x1 = x , let y1 = y else {
print("x&y沒值")
return
}
print(x1 + y1)
(4)guardlet和iflet能夠用同名變量接收。由於總會取名字,if let name = name這樣就能夠,注意後面使用的時候用非空的那個!而且iflet和guardlet能夠依次判斷,先判斷是一個字典,再拿字典的數組,在判斷數組的值,能夠一條線判斷出來。
(八)循環
(1)switch:
*(C中分支必須是整數,每個語句都須要break,若是要定義局部變量須要{}
* Swift能夠任意判斷,通常不須要break,多值判斷用逗號,全部分支都至少須要一條指令,若是什麼都不幹,纔要寫break
func demo(name : String) {
switch name {
case "guoguo","aixin":
print("guoguo")
default:
print("shit")
}
}
(2)for:swift取消了i++和++i和傳統的for循環
for i in 0...5 {
}
for i in 0..<5 {
}
(3)反序遍歷:
for i in (0..<10).reversed() {
}
(九)字符串:用String,是一個結構體,具備絕大多數NSString功能,支持直接遍歷
(1)遍歷:
func demo3() {
// 字符串遍歷(NSString不支持這麼遍歷)
let str = "wowosnshi是"
for s in str.characters {
print(s)
}
}
(2)長度:
// 返回指定編碼對應的字節數,每一個漢字三個字節
print(str.lengthOfBytes(using: .utf8))
// 返回真正字符串長度
print(str.characters.count)
(3)拼接:要注意可選項拼接不解決會帶上Optional,剩下的均可以拼接,不再用看StringWithFormat了
let name = "AA"
let age = 19
let title : String? = "sss"
print("\(name)\(age)\(title ?? "")")
(4)格式化:
*格式化成日期
let h = 8 , m = 10, s = 44
// OC中用stringWithFormat格式化日期,Swift中能夠
let strDate = String(format: "%02d-%02d-%02d", h,m,s)
print(strDate)
(5)截取字符串:建議用NSStrin做中轉,由於swift取串方法一直在改變
*NSString方法
let str = "紅紅火火恍恍惚惚"
let strOC = str as NSString
strOC .substring(to: 1)
strOC.substring(with: NSMakeRange(0, 2))
*3.0方法
(十)數組:
(1)就是中括號,注意數組的類型,而且基本數據類型不須要包裝,能夠直接方數組裏,若是類型不同(混合數組,可是基本不用),自動推導[NSObject]。在Swift中還有一個[AnyObject類型],標示任意對象,由於在Swift中一個類能夠沒有任何父類。
(2)遍歷:
let array = ["張三","李四","王五"]
// 遍歷1(按照下標遍歷)
for i in 0..<array.count {
}
// 遍歷2(遍歷元素)
for s in array {
}
// 遍歷3(同時遍歷下標和元素)
for e in array.enumerated() {
// let e: (offset: Int, element: String) e是一個元組
print("\(e.offset), \(e.element)")
}
// 遍歷4(同時遍歷下標和元素)
for (n,s) in array.enumerated() {
print("\(n),\(s)")
}
// 反序遍歷
for s in array.reversed() {
}
// 反序索引下標(這樣寫纔對,先枚舉再反序)
for (n,s) in array.enumerated().reversed() {
}
(3)增刪改:
array.append("AA")
array[1] = "BBB"
array.remove(at: 2)
(4)合併:用「+」號。可是要合併的數組的兩個類型必須一致。
(十一)字典:通常是[String:NSObject],對應鍵值對.因爲3.0後大部分都是結構體了,AnyObject很差用了,Any範圍更大
(1)字典數組:
(2)增刪改:和數組都相似,就是兩個字典合併不像數組直接相加,而是須要遍歷
(十二)SWift的類,結構體,枚舉三種都有構造函數,均可以有方法,就像OC的類。枚舉再swift變化很大,通常開發不會用到過高級語法。
(十三)函數:
(1)外部參數,當外部參數用_替代的時候,會在外部調用的時候忽略形參名
(2)函數的默認值(OC不具有),這個使Swift比OC靈活不少不少,一個方法能夠作不少事,由於OC會有各類參數和組合,Swift只需寫一個最多的參數,而後不須要的設定默認值就是了
3)無返回值 :直接省略 () Void均可以
(4)閉包:相似Block,比Block還普遍。OC中Block是匿名函數,Swift中函數是特殊的閉包。閉包在整個開發中和Block的應用場景同樣。用於控制器/自定義視圖/異步執行完成的回調。這些回調的特色就是都是以參數回調處理結果,返回值爲Void。
*定義:
let biBao = { (x: Int) -> Int in
return x + 100
}
print(biBao(10))
*GCD:將任務添加到隊列,指定執行任務的函數。任務就是Block/閉包,隊列以同步/異步的方式執行。
func loadData(compeletion:@escaping ( _ result: [String])->()) -> Void {
DispatchQueue.global().async {
print("耗時操做會得到一些結果 \(Thread.current)")
Thread.sleep(forTimeInterval: 1.0)
let json = ["天氣","不錯","颳大風"]
// 主線程回調
DispatchQueue.main.async(execute: {
print("主線程更新UI \(Thread.current)")
// 回調 -> 經過參數傳遞 執行閉包
compeletion(json)
})
}
}
調用:
// 執行的適合我就拿到了值
loadData { (result) in
print("獲取的新聞數據 \(result)")
}
*尾隨閉包:若是函數的最後一個參數是閉包,那麼參數就省略了,最後一個參數直接{}大括號包裝
*閉包的循環引用:
方法1
方法2
(5)面向對象(各類構造函數):()就是allocInit,在Swift中對應init()。在swift中一個項目全部類都是共享的,能夠直接訪問,每個類都默認有一個命名空間。A.name B.name God.name Dog.name。同一個類能夠從屬於不一樣的命名空間(假若有一個框架有Person類,作用戶,還有一個框架作後臺,也用Person。在OC中就只能靠前綴解決,HouTaiPerson,KuangJiaPerson。而Swift中的命名空間就是項目名。AAA項目有一個Person,那麼AAA.Person就是AAA的Person類,此時再導入框架,那也是框架的.Person)
*在自定義的Nsobjiect類中,has no initalizers 標示沒有初始化器,初始化器能夠有多個,默認是init。當這個類有屬性的時候,屬性要分配內存空間,就是說要有初始值。那麼其實就是先給本身的屬性分配,而後給父初始。其實這麼一看,Swift和OC是相反的!
思路:OC是先調用爸爸。就是Person,Person會再調用NSObject,就是先跑上去什麼都無論,先初始化了NSObject,而後才往下走挨個初始化。Swift是把本身徹底初始化,再上去初始化爸爸,這麼看比OC快了一圈,性能要好。
*重載構造函數:(重寫是父類有這個方法,override。重載是函數名相同,參數和個數不一樣。init就重寫,init+參數就重載。OC是沒有重載的!都是initWithXXXXX)。重載實際上是最基本的方式,OC沒有其實很low,可是Swift有。
注意:若是重載了構造函數而且沒有實現父類的init,那麼系統再也不提供init構造函數了(默認是有的),由於默認的構造函數不能給本類的屬性分配空間(你不本身寫name = ,系統就沒辦法分配)
nsobject類的isa屬性就是爲了記錄當前狀態的對象是什麼的,就是一個student對象,云云。在swift中打p能夠打印類內容
*KVC構造函數:只需記住下面4點
****因此通常在模型中加個? 而後用KVC實現(先調用init由於是運行時機制)
*模型中屬性定義:基本數據類型 = 0,對象設置?
運行時中,基本類型設置? 屬性設置私有都會讓運行時拿不到,此時kvc就會出錯。
*若是子類沒有重寫父類方法,調用的時候就會直接調用父類的方法。當繼承一個類,就繼承全部屬性和方法,包括KVC。當PERSON寫好了KVC後,
*總體
(6)便利構造函數:關鍵字Convenience(開發用的不多,由於模型都是框架轉,UI不須要便利)
*目的:條件判斷,只有知足條件才實例化對象,防止沒必要要的內存開銷,簡化對象建立。自己是不負責屬性的建立和初始化的。
說白了就是有些函數 帶個? 返回值能夠返回空,這就是便利構造函數的功勞。
* 主要用於條件檢查和控件建立。
在控件建立的時候,就不用?了,由於我就是爲了建立控件的。
(7)deinit:相似OC的Dealloc
(十四)分類:extension
便利構造函數 + 分類能夠省略抽取不少代碼。例如給UITextField/UIButton寫分類,而後寫便利構造函數,方便。
(十五): 運行時能夠獲取到一個對象的全部屬性方法等等,獲取到了屬性能夠KVC進行字典轉模型,這是全部第三方轉模型插件的基礎,獲取到了方法,能夠動態的發送各類方法。在swift中,若是一個基本變量Int什麼的用?修飾了,可選了。此時運行時是找不到的,因此KVC會崩潰,同時,若是修飾了private屬性,運行時也是找不到,KVC也會崩潰。其實在OC中,private是基本不用的,並且存不住任何私有,均可以被運行時找出來。可是swift就是真的藏起來了,找不到這個屬性和方法了外界。