swift各種demo社區(qū):https://www.hangge.com
一、
1、字符串的用法
let ?apples =3
let ? oranges =5
let ? appleSummary ="I have\(apples)apples."
let ? fruitSummary ="I have\(apples + oranges)pieces of fruit."
可以直接 用引號(hào) 進(jìn)行 把 數(shù)據(jù)類型進(jìn)行轉(zhuǎn)換 字符串!"\(number)"
Double精度問題
使用函數(shù) :String(format: <#T##String#>, <#T##arguments: CVarArg...##CVarArg#>)
var?f = 123.32342342
var?s:String?=?"\(f)"?//123.32342342 ? 小數(shù)全保留
var?s =?String(format:?"%.2f", f)?//123.32 ?小叔精確兩位
var s = String(format:?"%06x", i)?//000123.32342342 ?前面不足補(bǔ)零
二、
2、數(shù)據(jù)類型
Int ?一般來說,你不需要專門指定整數(shù)的長(zhǎng)度。Swift 提供了一個(gè)特殊的整數(shù)類型?Int,長(zhǎng)度與當(dāng)前平臺(tái)的原生字長(zhǎng)相同:
數(shù)值型類型轉(zhuǎn)換: ? ?【swift不同類型的數(shù)據(jù)類型不能 運(yùn)算!】!?。?!
1>整數(shù)轉(zhuǎn)換 ?let one: UInt8 = 1 ? ?UInt16(one)
2>整數(shù)和浮點(diǎn)數(shù)轉(zhuǎn)換?let three = 3 ?Double(three)
3、類型別名?typealias AudioSample = ?UInt16 ? //?typealias 別名 = ?原名
4、元祖的訪問:let http404Error = (404, "Not Found")
? 1>自定義變量 ?解析元祖?let (statusCode, statusMessage) = http404Error ? ?——>?print("The status code is \(statusCode)")
2>通過 ?【下標(biāo)】 ?來訪問元組中的單個(gè)元素,下標(biāo)從零開始:print("The status code is \(http404Error.0)")
3>通過 ?【名字】 ?來獲取這些元素的值(類似字典寫法):let http200Status = (statusCode: 200, description: "OK")
print("The status code is \(http200Status.statusCode)")
5、可選類型:Swift 中,nil?不是指針——它是一個(gè)確定的值,用來表示 值缺失。任何類型 ?的可選狀態(tài)都可以被 ?設(shè)置為?nil,
6、可選類型的解析值 ——>?可選綁定!
if let constantName = someOptional { statements} ? // 如果?someOptional有值得話,則會(huì)constantName會(huì)進(jìn)行賦值
這條語句不僅可以用來判斷可選類型中是否有值,同時(shí)可以將可選類型中的值賦給一個(gè)常量或者變量。
if someOptional != nil { } ?這樣就可以了!!
7、斷言和先決條件:斷言和先決條件的不同點(diǎn)是,他們什么時(shí)候進(jìn)行狀態(tài)檢測(cè):【斷言僅在調(diào)試環(huán)境運(yùn)行】,而 【先決條件則在調(diào)試環(huán)境和生產(chǎn)環(huán)境中運(yùn)行】。在生產(chǎn)環(huán)境中,斷言的條件將不會(huì)進(jìn)行評(píng)估。這個(gè)意味著你可以使用很多斷言在你的開發(fā)階段,但是這些斷言在生產(chǎn)環(huán)境中不會(huì)產(chǎn)生任何影響。
如果斷言或者先決條件中的布爾條件評(píng)估的結(jié)果為 true(真),則代碼像往常一樣繼續(xù)執(zhí)行?!?b>如果布爾條件評(píng)估結(jié)果為 false(假),程序的當(dāng)前狀態(tài)是無效的,則代碼執(zhí)行結(jié)束,應(yīng)用程序中止?!?/p>
1>斷言 (條件為假,則會(huì)觸發(fā) 斷言)
?let age = -3?
assert(age >= 0) // 省略 斷言信息
assert(age >= 0, "A person's age cannot be less than zero")// 因?yàn)?age < 0,所以斷言會(huì)觸發(fā) ——>?終止應(yīng)用。
2>先決條件
precondition(index > 0, "Index must be greater than zero.")
三、switch?
1、元組:元組中的元素可以是值,也可以是區(qū)間。另外,使用下劃線(_)來匹配所有可能的值。
let somePoint = (1, 1)?
switch somePoint {?
case (0, 0):?
? ? ? ? ? ? ? ?print("\(somePoint) is at the origin")?
case (_, 0):?
? ? ? ? ? ? ? ? print("\(somePoint) is on the x-axis")?
default:
? ? ? ? ? ? ? print("\(somePoint) is outside of the box")}
2、值綁定(Value Bindings)
let anotherPoint = (2, 0)?
switch anotherPoint {?
case (let x, 0):?
? ? ? print("on the x-axis with an x value of \(x)")?
case (0, let y):?
? ? ? print("on the y-axis with a y value of \(y)")?
case let (x, y) where x == y:?
? ? ? ?print("(\(x), \(y)) is on the line x == y")}
3、Where ? case 分支的模式可以使用?where?語句來判斷額外的條件。
4、復(fù)合型 Cases
let someCharacter: Character = "e"
?switch someCharacter {?
case "a", "e", "i", "o", "u":?
? ? ? ? ? ? print("\(someCharacter) is a vowel")?
case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":?
? ? ? ? ? ? print("\(someCharacter) is a consonant")?
default: print("\(someCharacter) is not a vowel or a consonant")}
四、檢測(cè)API可用性
if #available(平臺(tái)名稱 版本號(hào), ..., *) {?
? ? ? ? ? ? ?APIs 可用,語句將執(zhí)行} else {?
? ? ? ? ? ? ?APIs 不可用,語句將不執(zhí)行}
if #available(iOS 10, macOS 10.12, *) {
? ? ? ? ? ? ? ?// 在 iOS 使用 iOS 10 的 API, 在 macOS 使用 macOS 10.12 的 API} else {?
? ? ? ? ? ? ? ?// 使用先前版本的 iOS 和 macOS 的 API}
五、函數(shù)閉包 ——> 閉包 只是代碼!!只有在 觸發(fā)閉包時(shí),才會(huì)執(zhí)行代碼??!
1>逃逸閉包?@escaping:當(dāng)一個(gè) ?【閉包作為 參數(shù)】 傳到一個(gè)函數(shù)中,但是這個(gè) 【閉包在函數(shù) ?返回之后 才被執(zhí)行】,我們稱該閉包從函數(shù)中逃逸。定義接受閉包作為參數(shù)的函數(shù)時(shí),你可以在參數(shù)名之前標(biāo)注 【@escaping】
2>自動(dòng)閉包?@autoclosure (能不用就不用):(前提,閉包里就【一行表達(dá)式的閉包!!!!】 適合 用自動(dòng)閉包!?。╅]包里的執(zhí)行代碼 (直接—>去掉大括號(hào)) 作為參數(shù) 為顯式的閉包。——> 這個(gè)代碼不會(huì)執(zhí)行,只是一個(gè)參數(shù),在函數(shù)里閉包被調(diào)用時(shí)才會(huì)執(zhí)行!【有延遲執(zhí)行的效果?。。。∽鳛閰?shù)這行代碼只是代碼而不會(huì)執(zhí)行?。 ??【只有@autoclosure 修飾的閉包類型參數(shù) 才可以使用?】
過度使用?autoclosures?會(huì)讓你的代碼變得難以理解。上下文和函數(shù)名應(yīng)該能夠清晰地表明求值是被延遲執(zhí)行的。
注意:
1>Swift 有如下要求:只要在閉包內(nèi)使用?self?的成員,就要用?self.someProperty?或者?self.someMethod()(而不只是?someProperty?或?someMethod())。這提醒你可能會(huì)一不小心就捕獲了?self。
2>如果被捕獲的引用 ?絕對(duì)不會(huì)變?yōu)?nil,應(yīng)該用無主引用,而不是弱引用。【弱引用總是可選類型】,并且當(dāng)引用的實(shí)例被銷毀后,弱引用的值會(huì)自動(dòng)置為?nil。這使我們可以在閉包體內(nèi)檢查它們是否存在。
六、枚舉
1、枚舉訪問元素 。使用時(shí),【變量的類型不明確,則使用 Enum.item ? ? ?如果變量明確 直接使用 ? .item】
2、枚舉的遍歷:令枚舉遵循?CaseIterable?協(xié)議。Swift 會(huì)生成一個(gè)?allCases?屬性,用于表示一個(gè)包含枚舉所有成員的集合。
enum Beverage: CaseIterable {case coffee, tea, juice}
for beverage in?Beverage.allCases?{print(beverage)}
3、關(guān)聯(lián)值(代存儲(chǔ)):可以定義 Swift 枚舉來 ?【存儲(chǔ)任意類型的關(guān)聯(lián)值】前提 枚舉item 要設(shè)置 類型!——> 遍歷的時(shí)候,可以取 這關(guān)聯(lián)值! ?(設(shè)置類型 ——> 外部 賦值存儲(chǔ) ——> 遍歷 定義變量 取值 )
【關(guān)聯(lián)值 三法 ——> 設(shè)、賦、變!】
??原始值 :默認(rèn)值(稱為原始值)預(yù)填充,這些 ?原始值的類型必須相同!——> 設(shè)置枚舉的類型??!! 才可以有原始值
4、與 C 和 Objective-C 不同,Swift 的枚舉成員在被創(chuàng)建時(shí) ? ——> 不會(huì)被賦予一個(gè)默認(rèn)的整型值??!。在上面的?CompassPoint?例子中,north,south,east?和?west?不會(huì)被隱式地賦值為?0,1,2?和?3。相反,【這些枚舉成員本身就是完備的值】,這些值的類型是已經(jīng)明確定義好的?CompassPoint?類型。
enum Planet { case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune}
directionToHead = .south?
switch directionToHead {?
case .north: print("Lots of planets have a north")
?case .south: ?print("Watch out for penguins")?
case .east: print("Where the sun rises")?
case .west: print("Where the skies are blue")}
5、if case 語法、for case 語法 、guard case語法 ?http://www.itdecent.cn/p/f935c4db7333
七、結(jié)構(gòu)體和類
1、所有結(jié)構(gòu)體 ?都有一個(gè) 自動(dòng)生成的成員逐一構(gòu)造器,用于初始化新結(jié)構(gòu)體實(shí)例中成員的屬性。(默認(rèn)把所有屬性都帶上去了?。?!)
類:默認(rèn)是有一個(gè) init () {} ?構(gòu)造器,但是?構(gòu)造器里一個(gè)參數(shù)都沒有!!需要我們自己生產(chǎn)!構(gòu)造器
2、結(jié)構(gòu)體和枚舉? 是值類型? ——> 值類型是這樣一種類型,當(dāng)它被賦值給一個(gè)變量、常量或者被傳遞給一個(gè)函數(shù)的時(shí)候,其值會(huì)被拷貝。(但是 swift中集合、數(shù)組、字典 被優(yōu)化了,先共用 一個(gè)內(nèi)存空間,如有變動(dòng)則會(huì)再拷貝一份?。?/p>
3、屬性:類屬性,【必須賦值】!必須static和class關(guān)鍵字進(jìn)行修飾??!只第一次訪問時(shí)才初始化,且只初始化一次!
4、全局變量和局部變量:【全局變量】是在函數(shù)、方法、閉包或任何類型之外定義的變量?!揪植孔兞俊渴窃诤瘮?shù)、方法或閉包 ?內(nèi)部定義的變量。注意:【全局的常量或變量都是延遲計(jì)算的】!?。?!,跟?延時(shí)加載存儲(chǔ)屬性?相似,不同的地方在于,全局的常量或變量不需要標(biāo)記?lazy?修飾符。局部范圍的常量和變量從不延遲計(jì)算?!?gt;
【全局屬性定義的時(shí)候 內(nèi)部 set和get不進(jìn)行運(yùn)行,只有在用的時(shí)候 才 觸發(fā) set和get方法!】
【因?yàn)?變量 、常量 ?本質(zhì) 是 set/get 方法 ——> 方法只有在調(diào)用的時(shí)候才觸發(fā)!】
5、下標(biāo):定義下標(biāo)使用?subscript?關(guān)鍵字,與定義實(shí)例方法類似,都是指定一個(gè)或多個(gè)輸入?yún)?shù)和一個(gè)返回類型。與實(shí)例方法不同的是,下標(biāo)可以設(shè)定為讀寫或只讀。這種行為由 getter 和 setter 實(shí)現(xiàn),類似計(jì)算型屬性:
6、Any?可以表示 ?任何類型,包括函數(shù)類型。
? ??AnyObject?可以表示 ?任何類類型的—> 實(shí)例。 ? ? ?
八、擴(kuò)展 :必須自己實(shí)現(xiàn)
1>添加 ?計(jì)算型實(shí)例屬性和計(jì)算型類屬性? 【只能是 變量 var 而且 只能有 get方法??!】——> 只有g(shù)et方法!
并且 原有類已有的 ? 屬性 ? 和 方法 ? ?不可以 在 擴(kuò)展中 再 添加!!
2>擴(kuò)展 可以給一個(gè)類添加 ? 【新的便利構(gòu)造器!】,但是它們 ?【不能 添加 指定構(gòu)造器或者析構(gòu)器!??!】。【指定構(gòu)造器和析構(gòu)器必須 ? ?始終 ?由類 ?的原始實(shí)現(xiàn)提供】。
擴(kuò)展 && 協(xié)議 :
屬性:擴(kuò)展只可以 get方法 ?、協(xié)議 set/get 都可以
方法:類方法、對(duì)象方法 都可以
構(gòu)造器:擴(kuò)展 只可以 添加 遍歷構(gòu)造器 ?、協(xié)議 可以添加 指定構(gòu)造器 和 遍歷構(gòu)造器
九、協(xié)議 : 不用實(shí)現(xiàn)
1>類、結(jié)構(gòu)體或枚舉都可以遵循協(xié)議
2>協(xié)議通常!用 var 關(guān)鍵字來聲明變量屬性?,在類型聲明后加上 { set get } 來表示屬性是可讀可寫的,可讀屬性則用 { get }?來表示:
3>【協(xié)議中 ?可以添加 指定構(gòu)造器! 和 便利構(gòu)造器!】在?實(shí)現(xiàn)類?中 ——> 必須添加?關(guān)鍵字:required:必須實(shí)現(xiàn)
4> 協(xié)議 可以 當(dāng)作 一種 類型 ?使用:盡管協(xié)議本身并未實(shí)現(xiàn)任何功能,但是協(xié)議可以被當(dāng)做一個(gè)【功能完備的類型】來使用。協(xié)議作為類型使用,有時(shí)被稱作「存在類型」,這個(gè)名詞來自「存在著一個(gè)類型 T,該類型遵循協(xié)議 T」。
【協(xié)議作為類型 ——> 理解為 一個(gè) 特殊的泛型!! 只要是遵守這個(gè)類型的協(xié)議,都可以把 ?實(shí)例 賦值給這個(gè)參數(shù)!但是,這個(gè) 協(xié)議類型的參數(shù) 在使用過程中, 必須 使用 協(xié)議中的屬性和方法 ??。。?!】
5、在擴(kuò)展里添加協(xié)議遵循——> 讓原類 間接遵守這個(gè)協(xié)議
6、協(xié)議的繼承 ——> 給原有的協(xié)議 添加 新的協(xié)議!
7、協(xié)議擴(kuò)展:協(xié)議也可以進(jìn)行擴(kuò)展,【協(xié)議的 ?擴(kuò)展默認(rèn) ?可以 ?直接 ? 進(jìn)行實(shí)現(xiàn)該方法】!??!
8、可選的協(xié)議要求:??
1>【optional】?關(guān)鍵字作為前綴來定義可選要求 ?
2> 可選要求用在你需要和 Objective-C 打交道的代碼中。協(xié)議和可選要求都必須帶上?@objc?屬性?!?b>標(biāo)記?@objc?特性的協(xié)議只能被繼承自 Objective-C 類的類或者?@objc?類遵循】,其他類以及結(jié)構(gòu)體和枚舉均不能遵循這種協(xié)議。
嚴(yán)格來講,【@objc協(xié)議】?協(xié)議中的 ?【?方法和屬 ?性都是可選的】,因此遵循協(xié)議的類 可以不實(shí)現(xiàn)這些要求,盡管技術(shù)上允許這樣做,不過最好不要這樣寫。
9、協(xié)議合成:協(xié)議組合使用?SomeProtocol & AnotherProtocol?的形式,要求 【參數(shù)】 必須同時(shí)遵守多個(gè)協(xié)議!
十、循環(huán)引用:
1>?注意
如果被捕獲的引用絕對(duì)不會(huì)變?yōu)?nil,應(yīng)該用無主引用 unowned 。
弱引用:可能為nil空值 ?用 weak
十一、GCD用法
DispatchQueue ——>?DispatchObject ——>?OS_object ——>?NSObject ?//swift中的 ?DispatchQueue 集成 NSObject 是一個(gè) 類 !底層 runtime 執(zhí)行。
queue.suspend() //暫停
queue.resume() ?// 恢復(fù)
1>全局隊(duì)列 :
DispatchQueue.global(qos: .default).async { ? ? ?}//異步
DispatchQueue.global(qos: .default).sync { ? ? ?}//同步
2>自定義隊(duì)列
串行:let queue:DispatchQueue = DispatchQueue(label: "processQueueName") ?// 默認(rèn)串行 隊(duì)列
并發(fā): let queue:DispatchQueue = DispatchQueue(label: "processQueueName", attributes: .concurrent)
除了直接使用?DispatchQueue.global().async?這種封裝好的代碼外,還可以通過DispatchWorkItem自定義隊(duì)列的優(yōu)先級(jí),特性:
let queue = DispatchQueue(label: "swift_queue")
?let dispatchworkItem = DispatchWorkItem(qos: .userInitiated, flags: .inheritQoS) { } //可以開辟任務(wù)!
queue.async(execute: dispatchworkItem)
3>主隊(duì)列:DispatchQueue.main.async { ? ? ? }
4>線程組
DispatchQueue.global().async(group: DispatchGroup.init(), execute: DispatchWorkItem.init { ? ? ?//線程任務(wù) ? ? })
5>延遲定時(shí)器
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) { ? ?Print("延遲執(zhí)行的函數(shù)") ? ? }
6、swift中的單利:就是常量!
// 用let 創(chuàng)建常量?
static let shareSingleOne = SingleInstanceOne()
十二、不透明類型 (some + 協(xié)議名)

