Swift語言總結(jié)

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

協(xié)議

協(xié)議是方法的集合,它可以把看似不想關(guān)的對象的公共行為放到一個協(xié)議中丸逸。
協(xié)議在Swift開發(fā)中大致有三種作用:
1.能力 - 遵循了協(xié)議就意味著具備了某種能力某饰;
2.約定 - 遵循了協(xié)議就一定要去實(shí)現(xiàn)協(xié)議中的方法儒恋;
3.角色 -一個類可以遵循多個協(xié)議,一個協(xié)議可以被多個類遵循黔漂,遵循協(xié)議就意味著扮演了某種角色诫尽,遵循多個協(xié)議就意味著可以扮演多個角色。
Swift中的繼承是單一繼承(一個類只能有一個父類)炬守,如果希望讓一個類具備多重能力可以使用協(xié)議來實(shí)現(xiàn)牧嫉。

protocol Singsongs{
    func sing()
    }
protocol Teach{
    func teach()
}
class Student:singSongs{
    var name:String
    init(name:String){
    self.name = name
    }
    
    func sing(){
    print("\(name)正在唱歌")
    }
}

class Teacher:Singsongs,Teach{
    func teach(){
    print("老師正在教學(xué)生唱歌")
    }
    func Singsongs(){
    print("老師正在唱歌")
    }
}
    

協(xié)議擴(kuò)展

可以在協(xié)議擴(kuò)展中給協(xié)議中的方法提供默認(rèn)實(shí)現(xiàn),也就是說如果某個類遵循了協(xié)議但是沒有實(shí)現(xiàn)這個方法就直接使用默認(rèn)實(shí)現(xiàn)劳较,那么這個方法也就相當(dāng)于是一個可選方法(可以實(shí)現(xiàn)也可以不實(shí)現(xiàn))
在定義子類的時候必須先寫父類驹止,協(xié)議無關(guān)緊要

class Student:Human,Listen,Speak,Read,Write{
    var name:String
    init(name:String){
    self.name = name
    }
    func listen(){
    ...
    }
    ...
    ...
}

依賴倒轉(zhuǎn)原則(面向協(xié)議編程)

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

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

開閉原則

實(shí)現(xiàn)開閉原則最關(guān)鍵有兩點(diǎn):
1.抽象是關(guān)鍵(在設(shè)計系統(tǒng)的時候一定要設(shè)計好的協(xié)議)观蜗;
2.封裝可變性(橋梁模式 - 將不同的可變因素封裝到不同的繼承結(jié)構(gòu)中)
接口(協(xié)議)隔離原則:協(xié)議的設(shè)計要小而專不要大而全
協(xié)議的設(shè)計也要高度類聚

結(jié)構(gòu)

結(jié)構(gòu)大體上和類相仿臊恋,但是也有許多區(qū)別

struct Student{
    var name:String
    var age:Int
    func study(courseName:String){
    print("\(name)正在學(xué)習(xí)")
    }
}

區(qū)別1: 結(jié)構(gòu)的對象是值類型, 類的對象是引用類型
值類型在賦值的時候會在內(nèi)存中進(jìn)行對象的拷貝
引用類型在賦值的時候不會進(jìn)行對象拷貝只是增加了一個引用
結(jié)論: 我們自定義新類型時優(yōu)先考慮使用類而不是結(jié)構(gòu)除非我們要定義的是一種底層的數(shù)據(jù)結(jié)構(gòu)(保存其他數(shù)據(jù)的類型)
值類型的結(jié)構(gòu)
區(qū)別2: 結(jié)構(gòu)會自動生成初始化方法
區(qū)別3: 結(jié)構(gòu)中的方法在默認(rèn)情況下是不允許修改結(jié)構(gòu)中的屬性除非加上mutating關(guān)鍵字

//創(chuàng)建一個學(xué)生對象,然后用stu去引用它墓捻,所以此時學(xué)生對象引用計數(shù)為1
var stu:Student? = Student()
//此處沒有創(chuàng)建新的學(xué)生對象抖仅,原來的學(xué)生對象引用計數(shù)加1
var stu1 = stu
var stu2 = stu
var stu3 = stu

stu1 = nil
stu2 = nil
stu3 = nil
stu = nil
//附一個nil,引用計數(shù)-1當(dāng)引用計數(shù)為0砖第,ARC自動清理內(nèi)存釋放學(xué)生對象
//ARC即時性的內(nèi)存清理優(yōu)于Java中的Garbage Collection(垃圾回收)
var stu1:Student? = Student()
//強(qiáng)引用(strong(默認(rèn)))會增加引用計數(shù)撤卢,弱引用(weak)修飾的引用不會增加引用計數(shù)
weak var stu2 = stu1
weak var stu3 = stu2
stu1 = nil
//如果想釋放內(nèi)存 程序員可以手動將一個引用賦值為nil
var stu:Student?
func foo(){
    //stu是一個局部變量/常量 在函數(shù)調(diào)用結(jié)束后局部變量就消失了
    //所以學(xué)生對象的引用計數(shù)也就變成0了 所以會被ARC釋放掉
    let stu = Student()
    print(stu)
}

foo()
//創(chuàng)建任何子類對象的時候一定是先創(chuàng)建了父類對象
//引用轉(zhuǎn)移(會導(dǎo)致原來對象上的引用計數(shù)-1 新對象引用計數(shù) + 1)
var stu1: Person = Student()
var stu = Student()
var tea = Teacher()

自動釋放池

//通過向autoreleasepool函數(shù)中傳入一個閉包來實(shí)現(xiàn)
//autoreleasepool { () -> () in
    //自動釋放池中的對象引用在池的邊界會收到引用計數(shù)-1的消息
    //將來做iOS開發(fā)是某個地方會創(chuàng)建很多的臨時對象
    //那么最好在此處設(shè)置一個自動釋放池避免內(nèi)存瞬時峰值過高造成閃退
   // let  stu = Student()

//}

離開自動釋放池時 stu1會收到引用計數(shù)-1的消息 stu2也會收到引用計數(shù)-1的消息
如果程序中出現(xiàn)了類與類之間雙向關(guān)聯(lián)的關(guān)系 必須要將其中一端設(shè)置為weak引用
否則將會形成循環(huán)引用導(dǎo)致ARC無法釋放內(nèi)存

如果允許使用可空類型,通常使用weak來破除循環(huán)引用梧兼。如果不能使用可空類型放吩,就使用unowned來破除
如果員工對象關(guān)聯(lián)的部門對象被釋放了,如果還要員工對象去操作它所關(guān)聯(lián)的部門對象將導(dǎo)致程序崩潰
EXC_BAD_ACCESS

泛型 (generic)

讓類型不再是程序中的硬代碼(寫死的東西)

func bubbleSort<T: Comparable>(array: [T]) -> [T] {
    var newArray = array
    for i in 0..<newArray.count - 1 {
        var swapped = false
        for j in 0..<newArray.count - 1 - i {
            if newArray[j] > newArray[j + 1] {
                mySwap(&newArray[j], &newArray[j + 1])
                swapped = true
            }
        }
        if !swapped {
            break
        }
    }
    return newArray
}

// 定義一個虛擬類型T, 調(diào)用函數(shù)時根據(jù)傳入的參數(shù)類型來決定T到底是什么
func mySwap<T>(inout a: T, inout _ b: T) {
    let temp = a
    a = b
    b = temp
}

泛型限定

// <T: Comparable>限定T類型必須是遵循了Comparable協(xié)議的類型
func myMin<T: Comparable>(a: T, _ b: T) -> T {
    return a < b ? a : b
}


let array1: Array<Int> = [23, 45, 99, 12, 68, 51, 70, 66]
let array2 = bubbleSort(array1)
print(array1)
print(array2)

異常處理(Error Handling)

如果一個方法拋出了異常 那么在聲明方法時必須要寫上throws關(guān)鍵字
throws關(guān)鍵字是提醒方法的調(diào)用者方法可能會出狀況 調(diào)用時要寫try

    init(num: Int, den: Int) throws {
        _num = num
        _den = den
        if _den == 0 {
            // 如果程序中出現(xiàn)問題就拋出錯誤(異常)
            // 被throw關(guān)鍵字拋出的必須是遵循ErrorType協(xié)議的東西
            throw FractionError.ZeroDenominator
        }
        else {
            simplify()
            normalize()// 如果一個方法拋出了異常 那么在聲明方法時必須要寫上throws關(guān)鍵字
    // throws關(guān)鍵字是提醒方法的調(diào)用者方法可能會出狀況 調(diào)用時要寫try
    init(num: Int, den: Int) throws {
        _num = num
        _den = den
        if _den == 0 {
            // 如果程序中出現(xiàn)問題就拋出錯誤(異常)
            // 被throw關(guān)鍵字拋出的必須是遵循ErrorType協(xié)議的東西
            throw FractionError.ZeroDenominator
        }
        else {
            simplify()
            normalize()
        }
        }
    }
    func add(other: Fraction) -> Fraction {
        // 如果能夠確保方法調(diào)用時不出異常那么可以在try關(guān)鍵字后加!
        // 這樣就可以在不寫do...catch的情況下調(diào)用可能出狀況的方法
        return try! Fraction(num: _num * other._den + other._num * _den, den: _den * other._den)
    }

如果能夠保證代碼不出錯可以在try后面加!
如果不確定代碼是否出錯可以在try后面加?
需要注意的是有?的地方會產(chǎn)生Optional(可空類型)
稍后可能還需要對可空類型進(jìn)行拆封, 拆封方式有二:

  1. 不安全的做法: xxx!
  2. 安全的做法: 用if let = xxx { }進(jìn)行拆封
func foo() {
    
    let f1 = try? Fraction(num: 3, den: 0)
    let f2 = try? Fraction(num: 0, den: 9)
    
    if let a = f1, b = f2 {
        let f3 = a + b
        print(f3.info)
    }
    else {
        print("無效的分?jǐn)?shù)無法進(jìn)行加法運(yùn)算")
    }
}

foo()

對于可能出狀況的代碼要放在do...catch中執(zhí)行
在可能出狀況的方法前還要寫上try表示嘗試著執(zhí)行
如果在do中沒有出現(xiàn)任何狀況那么catch就不會執(zhí)行
如果do中出現(xiàn)了狀況代碼就不會再向下繼續(xù)執(zhí)行而是轉(zhuǎn)移到catch中
在do的后面可以跟上多個catch用于捕獲不同的異常狀況 但是最多只有一個catch會被執(zhí)行

//do {
//    let f1 = try Fraction(num: 3, den: 4)
//    let f2 = try Fraction(num: 0, den: 9)
//
//    print(f1.info)
//    print(f2.info)
//
//    let f3 = f1 + f2
//    print(f3.info)
//    let f4 = f1 - f2
//    print(f4.info)
//    let f5 = f1 * f2
//    print(f5.info)
//    let f6 = try f1 / f2
//    print(f6.info)
//}
//catch FractionError.ZeroDenominator {
//    print("瓜西西的, 分母不能為0!!!")
//}
//catch FractionError.DivideByZero {
//    print("卵球了, 除以0是不行的!!!")
//}
//catch {
//    print("出錯了! 我也不知道什么問題")
//}

計算機(jī)的硬件組成

計算機(jī)的硬件由五大部件構(gòu)成:
運(yùn)算器羽杰、控制器渡紫、存儲器、輸入設(shè)備考赛、輸出設(shè)備
運(yùn)算器 + 控制器 => CPU (中央處理器)
存儲器 => 內(nèi)存 (RAM - Random Access Memory)

程序員可以使用的內(nèi)存大致分為五塊區(qū)域:
棧 (stack) - 我們定義的局部變量/臨時變量都是放在棧上

  • 特點(diǎn): 小惕澎、快
    堆 (heap) - 我們創(chuàng)建的對象都是放在堆上的
  • 特點(diǎn): 大、慢
    靜態(tài)區(qū) (static area)
  • 數(shù)據(jù)段 - 全局量
  • 只讀數(shù)據(jù)段 - 常量
  • 代碼段 - 函數(shù)和方法

Swift語言階段總結(jié)

    經(jīng)過了三周的學(xué)習(xí)颜骤,把Swift的語法過了一遍唧喉,對這門編程語言也有了大致的了解了,雖然沒有什么基礎(chǔ)忍抽,但勉強(qiáng)還是跟上了進(jìn)度(應(yīng)該是跟上了吧>o<)八孝,不過呢,最大的毛病是總感覺能看懂怎么用鸠项,但自己一寫就不行了唆阿。可能是對某些語法理解不夠深的原因吧锈锤,不過這也再次提醒了我驯鳖,畢竟算不上高智商,不經(jīng)過無數(shù)的練習(xí)久免,是學(xué)不會的浅辙。而我現(xiàn)在的努力程度,貌似差的有點(diǎn)多阎姥。记舆。
    下一周又將迎來一個新的階段,雖然還不知道難度怎么樣呼巴,但是現(xiàn)在我也只能選擇向前泽腮,沒有退縮的余地御蒲。等以后成功的時候,總會感謝現(xiàn)在拼搏的自己诊赊,加油厚满!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市碧磅,隨后出現(xiàn)的幾起案子碘箍,更是在濱河造成了極大的恐慌,老刑警劉巖鲸郊,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丰榴,死亡現(xiàn)場離奇詭異,居然都是意外死亡秆撮,警方通過查閱死者的電腦和手機(jī)四濒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來职辨,“玉大人峻黍,你說我怎么就攤上這事〔Υ遥” “怎么了贬循?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵宴卖,是天一觀的道長。 經(jīng)常有香客問我,道長古程,這世上最難降的妖魔是什么岳颇? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任烫止,我火速辦了婚禮奈泪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘黎侈。我一直安慰自己察署,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布峻汉。 她就那樣靜靜地躺著贴汪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪休吠。 梳的紋絲不亂的頭發(fā)上扳埂,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機(jī)與錄音瘤礁,去河邊找鬼阳懂。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的岩调。 我是一名探鬼主播巷燥,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼号枕!你這毒婦竟也來了缰揪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤堕澄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后霉咨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛙紫,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年途戒,在試婚紗的時候發(fā)現(xiàn)自己被綠了坑傅。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡喷斋,死狀恐怖唁毒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情星爪,我是刑警寧澤浆西,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站顽腾,受9級特大地震影響近零,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜抄肖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一久信、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧漓摩,春花似錦裙士、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至夭咬,卻和暖如春酥诽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背皱埠。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工肮帐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓训枢,卻偏偏與公主長得像托修,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子恒界,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理睦刃,服務(wù)發(fā)現(xiàn),斷路器十酣,智...
    卡卡羅2017閱讀 134,659評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法涩拙,類相關(guān)的語法,內(nèi)部類的語法耸采,繼承相關(guān)的語法兴泥,異常的語法,線程的語...
    子非魚_t_閱讀 31,639評論 18 399
  • 蘋果官方文檔翻譯 《Objective-C語言編程》(Programming with Objective-C) ...
    fever105閱讀 25,684評論 19 130
  • 啊我的amxuqa啊ald u m
    huanghw閱讀 90評論 0 0
  • 夢很短虾宇,也沒有豺狼虎豹搓彻,卻把我驚醒。夢里的我們來到了一排殘破不堪的磚瓦房前嘱朽,腐爛的門楣旭贬,破碎的玻璃,樹葉早已把門前...
    賈學(xué)禮零售閱讀 108評論 0 0