Swift學習最終總結

語言基礎

程序是指令的集合始衅,寫程序就是寫一系列的指令去控制計算機做我們想做的事情。
編譯: 將程序設計語言轉換成計算機能夠理解的機器語言或者某種中間代碼的過程肠阱。

馮諾依曼體系結構的計算機:

  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有非常強大的類型推斷愉棱,所以定義變量或常量時,應該直接使用類型推斷哲戚,不用手動指定類型羽氮;
  2. 如果可以的話應該盡可能使用常量而不是變量。

語言元素

var a: Int = 101

關鍵字: 有特殊含義的單詞
標識符: 給變量惫恼、常量、函數(shù)澳盐、類祈纯、結構令宿、協(xié)議、枚舉腕窥、方法粒没、屬性等起的名字

命名規(guī)則:
1.字母(Unicode字符)、數(shù)字簇爆、下劃線癞松,數(shù)字不能開頭;
2.大小寫敏感(區(qū)分大小寫)入蛆;
3.不能使用關鍵字作標識符响蓉;
4.使用駝峰命名法(命名變量、常量哨毁、函數(shù)枫甲、方法、屬性扼褪,第一個單詞小寫想幻,從第二個單詞開始首字母大寫;命名類话浇、結構脏毯、協(xié)議、枚舉每個單詞首字母都要大寫)
5.見名知意幔崖;
6.命名私有的屬性和方法時以下劃線開頭食店。

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

1.賦值運算符: = 、+= 岖瑰、—= 叛买、...
2.算術運算符: + 、-蹋订、 *率挣、 /、 %
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{9a86}"
4.字符串字面量: "Hello" 培愁、 "caf\u{e9}"
5.布爾字面量: true、 false
6.空值字面量: nil
7.類型字面量: Sting.self雪位、 UILabel.self

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

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

分支和循環(huán)

分支結構

  • if...else...

下面的代碼實現(xiàn)了分段函數(shù)求值的功能雹洗。

let x = 3.2
let y: Double
if x < -1 {
    y = 3 * x + 5
}
else if x <= 1 {
    y = 5 * x - 3
}
else {
    y = 7 * x + 1
}
  • switch...case...default
let score = 92.5
let level: String
switch score {
    case 0...59:
        level = "D"
    case 60...70:
        level = "C"
    case 71...85:
        level = "B"
    case 85...100:
        level = "A"
    default:
        level = "?:輸入錯誤"
}
print(level)

循環(huán)結構

下面的程序?qū)崿F(xiàn)了1-100求和香罐。

  • while
var i = 1
var sum = 0 
while i <= 100 {
    sum += i
    i += 1
} 
print(sum)
  • repeat...while...
var i = 1
var sum = 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)")
        }
    }
}

說明
在循環(huán)中可以使用break關鍵字來提前終止循環(huán)时肿,也可以是用continue關鍵字使循環(huán)直接進入下一輪庇茫,但是應該盡量避免使用break和continue,因為它們不會讓你的程序變得更好螃成。

綜合案例: Craps賭博游戲????

游戲規(guī)則: 玩家搖骰子旦签,如果第一次搖出了7點活著11點,玩家勝寸宏;如果搖出了2點宁炫,3點或者12點,莊家勝氮凝;如果搖出了第一次搖的點數(shù)羔巢,玩家勝;否則游戲繼續(xù)直到分出勝負罩阵。

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

let firstPoint = roll() + roll()
print("玩家搖出了\(firstPoint)點")
var needsGoOn = false

switch firstPoint {
case 7,11:
    print("玩家勝")
    needsGoOn = false
case 2,3,12:
    print("莊家勝")
    needsGoOn = false
default:
    print("游戲繼續(xù)竿秆!")
    needsGoOn = true
}
while needsGoOn {
    let currentPoint = roll() + roll()
    print("玩家搖出了\(currentPoint)點")
    if currentPoint == 7 {
        print("莊家勝")
        needsGoOn = false
    }
    else if currentPoint == firstPoint {
        print("玩家勝")
        needsGoOn = false
    }
}

容器

數(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 array4 = Array[Int](count: 5, repeatedValue: 0)
  • 添加元素
array1.append(1)
array1.insert(1, atIndex: 1)
array1.insert(2, atIndex: array1.count)
array1 += [5]
array1 += [4,56,68,86]
  • 刪除元素
array1.removeAtIndex(2)
array1.removeFirst()
array1.removeLast()
array1.removeFirst(3)
array1.removeAll()
array1.removeRange(1...5)
  • 修改元素
array3[0] = 153545
array3[array.count - 1] = 1388
print(array3)
  • 遍歷數(shù)組

方式1:

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

方式2:

for temp in array3[1...3] {
    print(temp)
}

說明: for - in 循環(huán)是一個只讀循環(huán)傅是,這也就意味著在循環(huán)的過程中不能對數(shù)組中的元素進行修改匪燕。

方式3:

for (i, temp) in array3.enumerate() {
    print("\(i).\(temp)")
}

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

數(shù)組中的元素也可以是數(shù)組肚豺,因此我們可以構造多維數(shù)組。最常見的是二維數(shù)組界拦,它相當于是一個有行有列的數(shù)組,數(shù)組中的每個元素代表一行梗劫,該數(shù)組中的每個元素代表行里面的列享甸。二維數(shù)組可以模擬現(xiàn)實世界中的表格、數(shù)學上的矩陣梳侨、棋類游戲的棋盤蛉威、2D游戲的地圖。所以在實際開發(fā)中使用非常廣泛走哺。

下面是用二維數(shù)組模擬表格的例子:

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


let namesArray = ["張小凡","林驚羽","陸雪琪","碧瑤","田靈兒"]
let courseArray = ["語文","數(shù)學","英語"]

var scoresArray = [[Double]](count: 5, repeatedValue: [Double](count: 3, repeatedValue: 0))

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

for i in 0..<courseArray.count {
    for (index, array) in scoresArray.enumerate() {
        var sum = 0.0
        for score in array {
            sum += score
        }
        let avg = sum / Double(courseArray.count)
        print("\(namesArray[index])\(courseArray[i])的平均成績是: \(avg)")
    }
    var sum = 0.0
    for row in 0..<scoresArray.count {
        sum += scoresArray[row][i]
    }
    let avg = sum / Double(namesArray.count)
    print("\(courseArray[i]         )的平均成績是: \(avg)")
}

集合

集合在內(nèi)存中時離散的蚯嫌,集合中的元素通過計算Hash Code(哈希碼或散列碼)來決定存放在內(nèi)存中的什么位置。集合中不允許有重復元素丙躏。

  • 創(chuàng)建集合
var set: Set<Int> = [2,2,5,0,8,8,156,6]
  • 添加和刪除元素
set.insert(1)

set.remove(5)
set.removeFirst()
  • 集合運算(交集择示、并集、差集)
ar set1: Set<Int> = [0,1,2,3,4,5,6,7,8,9]
var set2: Set<Int> = [1,3,5,7,9]

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

字典

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

  • 創(chuàng)建字典
let dict Dictionary<Int, String> = [
    1: "Zhang Xiaofan",
    2: "Lin Jingyu",
    3: "Lu Xueqi",
    4: "Tian Ling er",
    5: "Bi Yao"
]
  • 添加元素废恋、刪除元素和修改元素

dict[4] = "Jin Ling er"

//dict.removeValueForKey(5)

dict[3] = "Xiao Hui"
dict[5] = nil
  • 遍歷元素
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
    2.sortInPlace

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

let array = [23,1456,465,46,1,143,13,153,135,135,14,354,35,4]

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

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

  • 過濾
let array = [23,1456,465,46,1,143,13,153,135,135,14,354,35,4]
// 篩選掉不滿足條件的數(shù)據(jù)
let newArray = array.filter { $0 > 50 }
print(newArray)
  • 映射
let array = [23,1456,465,46,1,143,13,153,135,135,14,354,35,4]

// 通過映射對數(shù)據(jù)進行變換處理
let newArray  = array.map { sqrt(Double($0)) }
print(newArray)
  • 歸約
let array = [23,1456,465,46,1,143,13,153,135,135,14,354,35,4]
let result_ = array.reduce(0, combine: +)
print(result_)

函數(shù)和閉包

函數(shù)是獨立的可重復使用的功能模塊鱼鼓,如果程序中出現(xiàn)了大量的重復代碼拟烫,通常都可以將這部分功能封裝成獨立的函數(shù)。在Swift中迄本,函數(shù)是"一等公民"硕淑,函數(shù)作為類型來使用,也就是說函數(shù)可以賦值給一個變量或常量岸梨,可以將函數(shù)作為函數(shù)的參數(shù)或者返回值喜颁,還可以使用高階函數(shù)。

func 函數(shù)名([參數(shù)名1: 類型, 參數(shù)2: 類型, ...]) [throws][rethrows] [-> 返回類型] 
{
    函數(shù)的執(zhí)行體
    [return表達式]
} 
  • 外部參數(shù)名(可省略)
func myMin(a x:Int, b y:Int) -> Int {
    return x < y ? x :  y
}
// 調(diào)用函數(shù)的時候要寫外部參數(shù)名
print(myMin(a: 3,b: 5))

func myMin(x:Int, _ b y:Int) -> Int {
    return x < y ? x :  y
}
// 調(diào)用函數(shù)的時候不用寫外部參數(shù)名
print(myMin(3, 5))
  • inout參數(shù)
    輸入輸出參數(shù)(不僅將數(shù)據(jù)傳入函數(shù)還要從函數(shù)中取出數(shù)據(jù))
func swap(inout a : Int ,inout _ b :Int ) -> Void {
    //(a, b) = (b, a)
    let temp = a
    a = b
    b = temp
}

var a = 15343 , b = 1553
// 函數(shù)調(diào)用傳參都是傳值
// inout類型的參數(shù)前要加上&符號
swap(&a, &b)
  • 可變參數(shù)列表
    Swift中函數(shù)的參數(shù)列表可以是可變參數(shù)列表(參數(shù)的個數(shù)是任意多個)
func sum(nums: Int...) -> Int {
    var total = 0
    for num in nums {
        total  += num
    }
    return total
}
// 調(diào)用的時候:
print(sum())
print(sum(32))
print(sum(1,2,3,4,2,3,486,48,5))
print(sum(1,23,36))

閉包就是沒有名字的函數(shù)或者稱之為函數(shù)表達式(Lambda表達式)曹阔,Objective-C中與之對應的概念叫block半开。如果一個函數(shù)的參數(shù)類型是函數(shù),我們可以傳入一個閉包赃份;如果一個函數(shù)的返回類型是函數(shù)我們可以返回一個閉包寂拆;如果一個類的某個屬性是函數(shù)奢米,我們也可以將一個閉包表達式賦值給它。

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


{ (parameters) -> return type in
    statements
}

面向?qū)ο缶幊?OOP)

基本概念

對象: 接收消息的單元纠永,對象是一個具體的概念鬓长。

類: 對象的藍圖和模板,類是一個抽象概念尝江。

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

四大支柱

抽象: 定義類的過程就是一個抽象的過程炭序,需要做數(shù)據(jù)臭西那個和行為抽象啤覆,數(shù)據(jù)抽象找到對象的屬性(保存對象狀態(tài)的存儲屬性),行為對象找到對象的方法(可以給對象發(fā)消息)惭聂。

封裝:
- 觀點一: 我們在類中寫方法其實就是在封裝API窗声,方法的內(nèi)部實現(xiàn)可能會很復雜,但是這些對調(diào)用者來說是不可見的辜纲,調(diào)用只能看到方法有一個簡單清晰的接口笨觅。
- 觀點二: 將對象的屬性和操作這些屬性的方法綁定在一起。
- 觀點三: 隱藏一切可以隱藏的實現(xiàn)細節(jié)耕腾,只提供簡單清晰的接口(界面)见剩。

繼承: 從已有的類繼承新的類的過程。

多態(tài): 同樣的引用類型幽邓,但做了不一樣點事情炮温。
重載 - overload
重寫 - override

三個步驟

1.定義類

  • 數(shù)據(jù)抽象
    • 存儲屬性
  • 行為抽象
    • 方法(寫到類里面的函數(shù)或者說跟對象綁定的行為就是方法)
      • 對象方法:給對象發(fā)的消息
      • 類方法:給類發(fā)的消息,與對象的狀態(tài)無關的方法
    • 計算屬性
  • 構造器
    • 指派構造器
    • 便利構造器(convenience)
    • 必要構造器(required)

2.創(chuàng)建對象
3.給對象發(fā)消息

class Triangle {
    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ā)給類的消息牵舵,與對象狀態(tài)無關)
    // 此處的static也可以換成class作用相同
    static func isValid(a: Double, b: Double, c: Double) -> Bool {
        return a + b > c && b + c > a && a + c > b
    }
    
    // 對象方法(發(fā)給對象的消息柒啤,與對象狀態(tài)有關)
    func perimeter() -> Double {
            return a + b + c
    }
    
}

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

相關內(nèi)容

  • 枚舉

  • 結構(體)

總結 類和結構的區(qū)別到底有哪些担巩?什么時候應該使用結構?什么時候應該使用類没炒?

  • 擴展(extension)

  • 運算符重載

  • 下標運算(subscript)

  • 訪問修飾符

    • private
    • internal
    • public

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

協(xié)議

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

1.能力:
2.約定:
3.角色:

依賴倒轉原則

設計模式

  • 代理模式
  • 用協(xié)議實現(xiàn)委托回調(diào)
    一個對象想做某件事情涛癌,但是自身沒有能力做這件事情就可以使用委托回調(diào),具體的步驟是:
    • 設計一個協(xié)議送火,被委托方要遵循協(xié)議并實現(xiàn)協(xié)議中的方法
    • 委托方有一個屬性是協(xié)議類型的拳话,通過該屬性可以調(diào)用協(xié)議中的方法

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

其他

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

泛型

讓類型不再是程序中的硬代碼(hard code)种吸,可以設計出更通用的代碼弃衍。

  • 泛型函數(shù)

  • 泛型類/結構/枚舉

相關知識

  • 泛型限定
  • where子句

錯誤處理

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

邊角知識

  • ARC
  • 正則表達式
  • 嵌套類型
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市坚俗,隨后出現(xiàn)的幾起案子镜盯,更是在濱河造成了極大的恐慌岸裙,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件速缆,死亡現(xiàn)場離奇詭異降允,居然都是意外死亡,警方通過查閱死者的電腦和手機艺糜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門剧董,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人倦踢,你說我怎么就攤上這事送滞。” “怎么了辱挥?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長边涕。 經(jīng)常有香客問我晤碘,道長,這世上最難降的妖魔是什么功蜓? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任园爷,我火速辦了婚禮,結果婚禮上式撼,老公的妹妹穿的比我還像新娘童社。我一直安慰自己,他們只是感情好著隆,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布扰楼。 她就那樣靜靜地躺著,像睡著了一般美浦。 火紅的嫁衣襯著肌膚如雪弦赖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天浦辨,我揣著相機與錄音蹬竖,去河邊找鬼。 笑死流酬,一個胖子當著我的面吹牛币厕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播芽腾,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼旦装,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了晦嵌?” 一聲冷哼從身側響起同辣,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤拷姿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后旱函,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體响巢,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年棒妨,在試婚紗的時候發(fā)現(xiàn)自己被綠了踪古。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡券腔,死狀恐怖伏穆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情纷纫,我是刑警寧澤枕扫,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站辱魁,受9級特大地震影響烟瞧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜染簇,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一参滴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧锻弓,春花似錦砾赔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至聚至,卻和暖如春酷勺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背扳躬。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工脆诉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贷币。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓击胜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親役纹。 傳聞我的和親對象是個殘疾皇子偶摔,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348

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