Swift的知識點總結(jié)

Swift學(xué)習(xí)總結(jié)

語言基礎(chǔ)

程序是指令的集合窍奋,寫程序就是寫一系列的指令去控制計算機做我們想做的事情。
編譯:將程序設(shè)計語言轉(zhuǎn)換成計算機能夠理解的機器語言或者某種中間代碼的過程。

馮諾依曼體系結(jié)構(gòu)的計算機:
1.使用二進制
2.程序存儲執(zhí)行

常量和變量

定義變量和常量是為了保存數(shù)據(jù)。變量和常量就是某種類型的值的存儲空間。
var a:Int = 10
a = 100 
var b:Int
b = 1000
var c = 10000
let d: Int = 10
// d = 100        // compiler error
let e = 1000

說明:
1.Swift有非常強大的類型推斷淘捡,
所以定義變量或常量時如果可以的話應(yīng)該
直接使用類型推斷不用手動指定類型;
2.如果可以的話應(yīng)該盡可能使用常量而不是變量池摧。

語言元素

var a:Int = 10

關(guān)鍵字:有特殊含義的單詞
標識符:你給變量焦除、常量、函數(shù)作彤、類膘魄、結(jié)構(gòu)、協(xié)議竭讳、方法创葡、屬性等起的名字

  1. 字母、數(shù)字绢慢、下劃線構(gòu)成蹈丸,數(shù)字不能開頭
  1. 大小寫敏感(區(qū)分大小寫)
  2. 不能使用關(guān)鍵字做標識符
  3. 使用駝峰命名法(命名變量、常量呐芥、函數(shù)逻杖、方法、屬性第一個單詞小寫思瘟,從第二個單詞開始每個首字母大寫荸百;命名類、結(jié)構(gòu)滨攻,够话、協(xié)議、枚舉每個單詞首字母都要大寫)
  4. 見名知意
  5. 命名私有的屬性和方法時以下劃線開頭

運算符:Swift中的運算符其實都是函數(shù)

1.賦值運算符:=光绕、+=女嘲、-=、....
2.算術(shù)運算符:+诞帐、-欣尼、*、/停蕉、%
3.比較運算符:==愕鼓、!=、<慧起、<=菇晃、>、>=
4.邏輯運算符:&&蚓挤、||磺送、!
5.條件運算符:?:
6.其他運算符:[]、.灿意、??估灿、?、!

字面(常)量:

1.整數(shù)字面量:10 脾歧、1_234_567甲捏、0x10、 0o10鞭执、0b10
2.小數(shù)字面量: 123.45司顿、1.2345e2、0xab.cdp2
3.字符字面量:"c"兄纺、"\n"大溜、"\u{41}"、"\u{9}"
4.字符串字面量:"Hello"估脆、"caf\u{e9}"
5.布爾字面量:true钦奋、false
6.空值字面量:nil
7.類型字面量:String.self、UILable.self

分隔符:將不同的語言元素符號分開

說明:
Swift中每個語句后面的分號是可寫可不寫的,寫代碼時盡量保證一行只有一條語句這樣就可以省略掉分號付材。

分支和循環(huán)

分支

  • if...else...
    下面的程序是判斷閏年的
print("請輸入年份:",terminator:"")
let year = inputInt()
if year % 4 == 0 && year % 100 != 0 && year % 400 == 0 {
    print("\(year)是閏年")
}
else {
    print("\(year)不是閏年")
}
  • switch...case...default
let score = 92.5
let level:String
switch score {
case 0..<60:
    level = "E"
case 60..<70:
    level = "D"
case 70..<80:
    level = "C"
case 80..<90:
    level = "B"
case 90...100:
    level = "A"
default:
    level = "輸入錯誤"
}
print(level)

循環(huán)

以求1+2+...+100的和為例朦拖。

  • while
var sum = 0
var i = 0
while i <= 100 {
    sum += i
    i += 1
}
print(sum)
  • repeat...while
var sum = 0
var i = 0
repeat {
    sum += i
    i += 1
}while i <=100
print(sum)
  • for
var sum = 0
for i in 1...100{
    sum += i
    }
}
print(sum)

窮舉法:窮盡所有可能性知道找到正確定答案
下面的程序?qū)崿F(xiàn)了"百錢百雞"問題的求解

for x in 0...20{
    for y in 0...33{
        let z = 100 - x - y
        if 5 * x + 3 * y + z / 3 == 100 && z % 3 == 0{
            print("\(x)只公雞,\(y)只母雞厌衔,\(z)只小雞")
        }
    }
}
//0只公雞璧帝,25只母雞,75只小雞
//4只公雞富寿,18只母雞睬隶,78只小雞
//8只公雞,11只母雞页徐,81只小雞
//12只公雞苏潜,4只母雞,84只小雞

說明:
在循環(huán)中可以使用break關(guān)鍵字來提前終止循環(huán)变勇,也可以使用continue關(guān)鍵字使循環(huán)直接進入下一輪恤左,但是應(yīng)該盡量減少對break和continue的使用,因為它們不會讓你的程序變得更好贰锁。

綜合案例: Craps賭博游戲赃梧。

游戲規(guī)則: 玩家搖兩顆色子,如果第一次搖出了7點或11點豌熄,玩家勝授嘀;如果搖出2、3锣险、12點蹄皱,莊家勝;其他的點數(shù)游戲繼續(xù)芯肤。在繼續(xù)的過程 中玩家重新?lián)u色子巷折,如果搖出了七點,莊家勝崖咨;如果搖出了與第一次一樣的點數(shù)锻拘,玩家勝;否則游戲繼續(xù)击蹲。

func roll() -> Int {
    return Int(arc4random_uniform(6)) + 1
}

var money = 10000

repeat {
    print("玩家總資產(chǎn):\(money)")

var debt:Int
repeat {
    print("請下注:",terminator:"")
    debt = inputInt()
}while debt <= 0 || debt > money


var needsGoOn = false
let firstPoint = roll() + roll()
print("玩家搖出了\(firstPoint)點")
switch firstPoint {
case 7,11:
    print("玩家勝")
    money += debt
case 2,3,12:
    print("莊家勝")
    money -= debt
default:
    needsGoOn = true
}



while needsGoOn {
    let currentPoint = roll() + roll()
    print("玩家搖出了\(currentPoint)點")
    if currentPoint == 7{
        print("莊家勝署拟!")
        money -= debt
        needsGoOn = false
    }
    else if currentPoint == firstPoint {
        print("玩家勝!")
        money += debt
        needsGoOn = false
    }
}

}while money > 0
print("你破產(chǎn)了!!!")


容器

數(shù)組

數(shù)組時使用連續(xù)的內(nèi)存空間保存多個同類型的元素的容器歌豺,因為數(shù)組中的元素在內(nèi)存中是連續(xù)的推穷,所以可以使用下標運算來訪問數(shù)組中的元素,實現(xiàn)隨機存取类咧。

  • 創(chuàng)建數(shù)組
var array1: [Int] = []
var array2: Array<Int> = []
var array3 = [1,2,3,4,5]
var array4 = [Int](count:5,repeatedValue: 0)
var array5 = Array<Int>(count:5,repeatedValue: 0)

  • 添加元素
array1.append(2)
array1.append(3)
array1.insert(1, atIndex: 0)
array1.insert(4, atIndex: array1.count)
array1 += [5]
array1 += [6,7,8]
  • 刪除元素
array1.removeAtIndex(2)
array1.removeFirst()
array1.removeFirst(2)
array1.removeLast()
array1.removeRange(1...2)
array1.removeAll()
  • 修改元素
array3[0] = 100
array3[array3.count - 1] = 500
print(array3)
  • 遍歷數(shù)組

1.方式1

for i in 0...array3.count {
    print(array3[i])
}

2.方式2

    for temp in array3 {
        print(temp)
    }

說明:for-in循環(huán)是一個只讀循環(huán)馒铃,這也意味著在循環(huán)的過程中不能對循環(huán)進行修改蟹腾。

3.方式3

for (i,temp) in array3.enumerate() {
    if i == 0 {
        array3[i] = 1
    }
    print("\(i),\(temp)")
}

提醒:
操作數(shù)組時最重要的是不要越界訪問元素。數(shù)組對象的count屬性表明了數(shù)組中有多少個元素区宇,那么有效的索引(下標)范圍是0到count-1.

數(shù)組中的元素也可以是數(shù)組娃殖,因此我們可以構(gòu)造多位數(shù)組。最常見的是二維數(shù)組萧锉,它相當于是一個有行有列的數(shù)組珊随,數(shù)組中的每個元素代表一行該數(shù)組中的每個元素代表行中的列,二維數(shù)組可以模擬現(xiàn)實世界中的表格柿隙、數(shù)學(xué)上的矩陣、棋類游戲的棋盤鲫凶、各類2D游戲的地圖禀崖,所以在實際開發(fā)中使用非常廣泛。

下面的程序使用二維數(shù)組模擬表格的例子

func randomInt(min: UInt32, max: UInt32) -> Int {
    return Int(arc4random_uniform(max - min + 1) + min)
}


let namesArray = ["關(guān)羽","張飛","趙云","馬超","黃忠"]
let coursesArray = ["語文","數(shù)學(xué)","英語"]

var scoresArray = [[Double]](count: namesArray.count, repeatedValue: [Double](count: coursesArray.count, repeatedValue: 0))


for i in 0..<scoresArray.count {
    for j in 0..<scoresArray[i].count {
        scoresArray[i][j] = Double(randomInt(0,max: 100))
    }
}

for (index, array) in scoresArray.enumerate() {
    var sum = 0.0
    for score in array {
        sum += score
    }
    let avg = sum / Double(coursesArray.count)
    print("\(namesArray[index])的平均成績?yōu)椋篭(avg)")
}

for i in 0..<coursesArray.count {
    var sum = 0.0
    for row in 0..<scoresArray.count {
        sum += scoresArray[row][i]
    }
    let avg = sum / Double (namesArray.count)
    print("\(coursesArray[i])的平均成績?yōu)椋篭(avg)分")
}

集合

集合在內(nèi)存中是離散的螟炫,集合中的元素通過計算Hash Code(哈希碼或散列碼)來決定存放在內(nèi)存中的什么位置波附,集合中不允許有重復(fù)元素。

  • 創(chuàng)建集合
var set: Set<Int> = [1,2,1,2,3,5]

  • 添加元素
set.insert(100)
  • 刪除元素
set.remove(5)
set.removeFirst()
set.removeAll()
  • 集合遍歷
for temp in set {
    print(temp)
}
  • 集合運算(交集昼钻、并集掸屡、差集)
var set1: Set<Int> = [1, 2, 1, 2, 3, 5]
var set2: Set<Int> = [1, 3, 5, 7]

set1.intersect(set2)
set1.union(set2)
set1.subtract(set2)

字典

字典是以鍵值對的方式保存數(shù)據(jù)的容器,字典中的每個元素都是鍵值對組合,通過鍵可以找到對應(yīng)的值然评。

  • 創(chuàng)建字典
var dict: [Int: String] = [
    1: "hello",
    2: "good",
    3: "nima",
    5: "vaafa"
]

  • 添加仅财、修改、刪除元素
print(dict[1]!)
if let str = dict[1] {
    print(str)
}
else {
    print("找不到")
}

dict[3] = "bfafafv,xmv"
dict[4] = "shit"
dict[5] = nil
dict.count

  • 遍歷元素
for key in dict.keys {
    print("\(key)----> \(dict[key]!)")
}

for value in dict.values {
    print(value)
}

for (index,value) in dict.enumerate() {
    print("\(index).\(value.0) ----> \(value.1)")
}

重要操作

  • 排序
  1. sort
let a = [1,3,2,5,7,4,9,8,6]
let b = a.sort(<)
print(b)
  1. sortInPlace
var a = [1,3,2,5,7,4,9,8,6]
a.sortInPlace(<)
print(a)

說明:
排序方法的參數(shù)是一個閉包(closure)碗淌,該閉包的作用是比較數(shù)組中的兩個元素的大小盏求。

let array = [23,45,12,89,98,55,7]

array.sort({(one: Int, two: Int) -> Bool in
    return one < two
})

array.sort({(one, two) in one < two })
array.sort({one, two in one < two })
array.sort({ $0 < $1 })
array.sort { $0 < $1 }
array.sort(<)

  • 過濾
let array = [23,45,12,89,98,55,7]
//篩選掉不滿足條件的數(shù)據(jù)
let newArray = array.filter { $0 > 50}
print(newArray)  //[89, 98, 55]
  • 映射
let array = [23,45,12,89,98,55,7]
//通過映射對數(shù)據(jù)進行變換處理
let newArray = array.map{ $0 % 10 }
print(newArray)
  • 歸約
let array = [23,45,12,89,98,55,7]
let newArray1 = array.filter { $0 > 50}
print(newArray1)
let newArray2 = array.map{ $0 % 10 }
print(newArray2)
let result = newArray2.reduce(0, combine: +)
print(result)

函數(shù)和閉包

函數(shù) 是獨立的可重復(fù)的功能模塊,如果程序中出現(xiàn)了大量的重復(fù)代碼亿眠,通常都可以將這部分功能封裝成一個獨立的函數(shù)碎罚。在swift中,函數(shù)是"一等公民"可以作為類型來使用纳像,也就是說函數(shù)可以賦值給一個變量或常量荆烈,可以將函數(shù)作為函數(shù)的參數(shù)或返回值,還可以使用高階函數(shù)竟趾。

func 函數(shù)名([參數(shù)1: 類型,參數(shù)2: 類型, ...]) [throws|rethrows] [->返回類型] {
    函數(shù)的執(zhí)行體
    [return 表達式]
}

  • 外部參數(shù)名
//調(diào)用函數(shù)的時候要寫函數(shù)的外部參數(shù)名
print(myMin(a: 3,b: 5))
  • inout參數(shù)
//inout - 輸入輸出參數(shù)(不僅將數(shù)據(jù)傳入函數(shù)還要從函數(shù)中取出數(shù)據(jù))
func createX(inout x: Int) {
    x = 1000
}
var x =  1
createX(&x)
print(x)
  • 可變參數(shù)列表(參數(shù)可以是任意多個)
func sum(nums:Int...) -> Int {
    var total = 0
    for num in nums {       //給了多少數(shù)憔购,就循環(huán)多少次
        total += num
    }
    return total
}

print(sum())
print(sum(999))
print(sum(1,2,3))
print(sum(90,82,37,68,55,11,99))

閉包 就是沒有名字的函數(shù)或者稱之為函數(shù)表達式(lambda表達式),Objective-C中與之對應(yīng)的概念叫block潭兽。如果一個函數(shù)的參數(shù)類型是函數(shù)我們可以傳入一個閉包倦始;如果一個函數(shù)的返回類型時函數(shù)我們可以返回一個閉包;如果一個類的某個屬性是函數(shù)我們也可以講一個閉包表達式賦值給它山卦。

{ ([參數(shù)列表]) [-> 返回類型] in 代碼}

面向?qū)ο缶幊蹋∣OP)

基本概念

對象:接受消息的單元鞋邑,對象是一個具體的概念

類:對象的藍圖和模版诵次,類是一個抽象概念

消息:對象之間通信的方式,通過給對象發(fā)消息可以讓對象執(zhí)行對應(yīng)的操作來解決問題枚碗。

四大支柱

抽象

  • 定義類的過程就是一個抽象的過程逾一,需要做數(shù)據(jù)抽象和行為抽象,數(shù)據(jù)抽象找到對象的屬性(保存對象狀態(tài)的存儲屬性)肮雨,行為抽象找到對象的方法(可以給對象發(fā)的消息)遵堵。

封裝:

  • 觀點1: 我們在類中寫方法其實就是在封裝API,方法的內(nèi)部實現(xiàn)可能會很復(fù)雜怨规,但是這是對調(diào)用者來說是不可見的陌宿,調(diào)用只能看到方法有一個簡單清晰的接口叉庐。
  • 觀點2: 將對象的屬性和操作這些屬性的方法綁定在一起纺棺。
  • 觀點3: 隱藏一切可以隱藏的實現(xiàn)細節(jié),只提供簡單清晰的接口(界面)莺戒。

繼承:

  • 從已有的類創(chuàng)建新的新類的過程
    提供繼承信息的稱為父類(超類/基類)
    得到繼承信息的稱為子類(派生類/衍生類)

多態(tài)

  • 同樣的對象類型(pet類型)
    接收相同的消息(調(diào)用相同的方法)
    但是做了不同的事情
    這就是多態(tài)(polymorphism)
  • 實現(xiàn)多態(tài)的關(guān)鍵步驟:
      1. 方法重寫(子類在繼承父類的過程中
        對父類已有的方法進行重寫掰烟,
        而且不同的子類給出各自不同的實現(xiàn)版本)
      1. 對象造型(將子類對象當成父類型來使用)

三個步驟

1.定義類

  • 數(shù)據(jù)抽象
    • 存儲屬性
  • 行為抽象
    • 方法:
      • 對象方法
      • 類方法
    • 計算屬性
  • 構(gòu)造器
    • 指派構(gòu)造器
    • 便利構(gòu)造器
    • 必要構(gòu)造器

2.創(chuàng)建對象

3.給對象發(fā)消息

class Triangel {
    var a:Double
    var b:Double
    var c:Double
    
    init(a:Double,b:Double,c:Double){
        self.a = a
        self.b = b
        self.c = c
    }
    
   //這個方法是發(fā)給三角形這個類的爽蝴,不是三角形這個對象的。就像是三角形自帶屬性纫骑,不傳入abc無法對這個類實現(xiàn)蝎亚,
    // 類方法(發(fā)給類的消息與對象狀態(tài)無關(guān))
    // 此處的static也可以換成class作用相同
    static func isValid(a:Double,_ b:Double,_ c:Double) -> Bool {
        return a + b > c && a + c > b && b + c > a
    }
    // 對象方法(發(fā)給對象的消息與對象狀態(tài)有關(guān))
    func perimeter() -> Double{
        return a + b + c
    }
}
// 在創(chuàng)建對象前先調(diào)用類方法

let a = 3.0
let b = 3.0
let c = 3.0
// 在創(chuàng)建對象前先調(diào)用類方法給定的三條邊能否構(gòu)成三角形
// 類方法是發(fā)給類的消息所以不用創(chuàng)建對象直接通過類名調(diào)用
if Triangel.isValid(a,  b,  c) {
    let t = Triangel(a: a, b: b, c: c)
    // 對象方法是發(fā)給對象的消息要先創(chuàng)建對象才能用
    print(t.perimeter())
}
else {
    print("無法創(chuàng)建三角形")
}

相關(guān)內(nèi)容

  • 枚舉

GET:枚舉是定義符號常量的最佳方式
GET:符號常量總是優(yōu)于字面常量

  • 結(jié)構(gòu)(體)

總結(jié): 類和結(jié)構(gòu)的區(qū)別有哪些?什么時候用結(jié)構(gòu)什么時候用類(絕大時候用類先馆,如果定義底層結(jié)構(gòu)才使用結(jié)構(gòu))

 區(qū)別1: 結(jié)構(gòu)的對象是值類型, 類的對象是引用類型
值類型在賦值的時候會在內(nèi)存中進行對象的拷貝
引用類型在賦值的時候不會進行對象拷貝只是增加了一個引用
結(jié)論: 我們自定義新類型時優(yōu)先考慮使用類而不是結(jié)構(gòu)
 除非我們要定義的是一種底層的數(shù)據(jù)結(jié)構(gòu)(保存其他數(shù)據(jù)的類型)
// 類
class Student1 {
    var name: String
    var age: Int
    var tel: String?
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    
    func getOlder() {
        age += 1
    }
    
    func study(courseName: String) {
        print("\(name)正在學(xué)習(xí).")
    }
}
//結(jié)構(gòu)體
struct Student2 {
    var name: String
    var age: Int
    
    func study(courseName: String) {
        print("\(name)正在學(xué)習(xí).")
    }
    
    // 區(qū)別3: 結(jié)構(gòu)中的方法在默認情況下是不允許修改結(jié)構(gòu)中的屬性除非加上mutating關(guān)鍵字
    mutating func getOlder() {
        age += 1
    }
}
 引用類型的類
let stu1 = Student1(name: "阿郎", age: 35)
var stu3 = stu1     // 此處內(nèi)存中仍然只有一個學(xué)生對象
stu3.name = "羅小號"
stu3.age = 18
print(stu1.name)
print(stu1.age)

 值類型的結(jié)構(gòu)
 區(qū)別2: 結(jié)構(gòu)會自動生成初始化方法
let stu2 = Student2(name: "阿郎", age: 35)
var stu4 = stu2     // 此處內(nèi)存中會復(fù)制一個新的學(xué)生對象
stu4.name = "王大錘"
stu4.age = 18
print(stu2.name)
print(stu2.age)


 區(qū)別2: 結(jié)構(gòu)會自動生成初始化方法
 區(qū)別3: 結(jié)構(gòu)中的方法在默認情況下是不允許修改結(jié)構(gòu)中的屬性
 除非加上mutating關(guān)鍵字
  • 擴展(extension)

如果在某個特定的應(yīng)用場景中你發(fā)現(xiàn)現(xiàn)有的類缺少某項功能
那么可以通過類擴展(extension)的方式現(xiàn)場添加這項功能

  • 運算符重載
class Fraction {
    private var _num:Int   //分子
    private var _den:Int  //分母
    
    var info:String {
        get {
            return _num == 0 || _den == 1 ? "\(_num)" : "\(_num)/\(_den)"
        }
    }
    
    init(num: Int, den: Int) {
        _num = num
        _den = den
    }
    
   
    // 加
    func add(other:Fraction) -> Fraction {
        return Fraction(num: _num * other._den + other._num * _den, den: _den * other._den).simplify().normalize()
    }
    // 減
    func sub(other:Fraction) -> Fraction {
        return Fraction(num: _num * other._den - other._num * _den, den: _den * other._den).simplify().normalize()
    }
    // 乘
    func mul(other:Fraction) -> Fraction {
        return Fraction(num: _num * other._num, den: _den * other._den).simplify().normalize()
    }
     //  除
    func div(other:Fraction) -> Fraction {
        return Fraction(num: _num * other._den, den: _den * other._num).simplify().normalize()
    }

    //將負號放到分子上
    func normalize() -> Fraction {
        if _den < 0 {
            _num = -_num
            _den = -_den
        }
        return self
    }
    
    // 化簡
    func simplify() -> Fraction {
        if _num == 0 {
            _den = 1
        }
        else {
            let x = abs(_num)
            let y = abs(_den)
            let g = gcd(x, y)
            _num /= g
            _den /= g
        }
        return self
    }
}


//運算符重載(為自定義的類型定義運算符)

func +(one:Fraction, two:Fraction) -> Fraction {
    return one.add(two)
}

func -(one:Fraction, two:Fraction) -> Fraction {
    return one.sub(two)
}

func *(one:Fraction, two:Fraction) -> Fraction {
    return one.mul(two)
}

func /(one:Fraction, two:Fraction) -> Fraction {
    return one.div(two)
}


  • 下標運算(subscript)
  • 訪問修飾符
    • private
    • internal
    • public

存儲屬性通常是Private的发框,因為數(shù)據(jù)要保護起來
方法一般是Public的 因為方法是對象接受的消息
如果自定義的類沒有打算在其他項目中使用 可以不寫訪問修飾符
直接使用默認的internal修飾符表示在本項目中公開對其他項目私有

面向協(xié)議編程(POP)

協(xié)議中全是抽象概念(只有聲明沒有實現(xiàn))
遵循協(xié)議的類可以各自對協(xié)議中的計算屬性和方法給出自己的實現(xiàn)版本,
這樣當我們面對協(xié)議編程的時候就可以把多態(tài)的優(yōu)勢發(fā)揮到淋漓盡致
可以寫出更通用更靈活的代碼(符合開閉原則)

協(xié)議

是方法的集合(計算屬性相當于就是方法)
可以把看似不相關(guān)的對象的公共行為放到一個協(xié)議中

protocol 協(xié)議名[:父協(xié)議1磨隘,父協(xié)議2, ...] {
    //方法的集合(計算屬性相當于就是方法)
}

協(xié)議在Swift開發(fā)中大致有三種作用:

  1. 能力 - 遵循了協(xié)議就意味著具備了某種能力
  2. 約定 - 遵循了協(xié)議就一定要實現(xiàn)協(xié)議中的方法
  3. 角色 - 一個類可以遵循多個協(xié)議缤底,
    一個協(xié)議可以被多個類遵循,
    遵循協(xié)議就意味著扮演了某種角色番捂,
    遵循多個協(xié)議就意味著可以扮演多種角色

依賴倒轉(zhuǎn)原則

說明:

  1. 聲明變量的類型時應(yīng)該盡可能使用協(xié)議類型
  2. 聲明方法參數(shù)類型時應(yīng)該盡可能使用協(xié)議類型
  3. 聲明方法返回類型時應(yīng)該盡可能使用協(xié)議類型

用協(xié)議實現(xiàn)委托回調(diào)

一個對象想做某件事情但是自身沒有能力去做這件事情就可以使用委托回調(diào)个唧,具體的步驟是:

  1. 設(shè)計協(xié)議,讓被委托方要遵循協(xié)議并實現(xiàn)協(xié)議中的方法
  2. 委托方有個屬性是協(xié)議類型的设预,通過該屬性可以調(diào)用協(xié)議中的方法

注意: 委托方的協(xié)議類型屬性通常是可空類型徙歼,因為要寫出weak引用

其他

  • 協(xié)議組合:protocol<協(xié)議1,協(xié)議2鳖枕,...>

  • 可選方法

  • 協(xié)議擴展:對協(xié)議中的方法給出默認實現(xiàn)

設(shè)計模式

  • 代理模式
  • 委托回調(diào)
    • 設(shè)計一個協(xié)議魄梯,讓被委托方遵循協(xié)議并實現(xiàn)協(xié)議中的方法
    • 委托方有一個屬性是協(xié)議類型的,通過該屬性可以調(diào)用協(xié)議中的方法
    • 委托方的協(xié)議類型屬性通常是可空類型宾符,因為要寫成weak(弱)引用酿秸。

其他

  • 協(xié)議組合: protocol<協(xié)議1,協(xié)議2魏烫,...>
  • 可選方法
  • 協(xié)議擴展:對協(xié)議中的方法給出默認實現(xiàn)

泛型

讓類型不再是程序中的硬代碼(hard code)辣苏。

  • 泛型函數(shù)
  • 泛型類/結(jié)構(gòu)/枚舉

相關(guān)知識

  • 泛型限定
  • where子句

錯誤處理

enum MyError: ErrorType {
    case A
    case B
    case c
}
  • throw
  • throws/ rethrows
  • do
  • catch
  • try

邊角知識

  • ARC
  • 正則表達式
  • 嵌套類型
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末肝箱,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子稀蟋,更是在濱河造成了極大的恐慌煌张,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件退客,死亡現(xiàn)場離奇詭異骏融,居然都是意外死亡,警方通過查閱死者的電腦和手機萌狂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門档玻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人粥脚,你說我怎么就攤上這事窃肠。” “怎么了刷允?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長碧囊。 經(jīng)常有香客問我树灶,道長,這世上最難降的妖魔是什么糯而? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任天通,我火速辦了婚禮,結(jié)果婚禮上熄驼,老公的妹妹穿的比我還像新娘像寒。我一直安慰自己,他們只是感情好瓜贾,可當我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布诺祸。 她就那樣靜靜地躺著,像睡著了一般祭芦。 火紅的嫁衣襯著肌膚如雪筷笨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天龟劲,我揣著相機與錄音胃夏,去河邊找鬼。 笑死昌跌,一個胖子當著我的面吹牛仰禀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蚕愤,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼答恶,長吁一口氣:“原來是場噩夢啊……” “哼饺蚊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起亥宿,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤卸勺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后烫扼,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體曙求,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年映企,在試婚紗的時候發(fā)現(xiàn)自己被綠了悟狱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡堰氓,死狀恐怖挤渐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情双絮,我是刑警寧澤浴麻,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站囤攀,受9級特大地震影響软免,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜焚挠,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一膏萧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蝌衔,春花似錦榛泛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至亩冬,卻和暖如春艘希,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背硅急。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工覆享, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人营袜。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓撒顿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親荚板。 傳聞我的和親對象是個殘疾皇子凤壁,可洞房花燭夜當晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容