swift語法02

Swift面向?qū)ο?/h1>

01-閉包的循環(huán)引用

  • 循環(huán)引用形成條件
    • 閉包中訪問了self或者self的屬性/方法
    • 必須有一個強(qiáng)引用的指針指向函數(shù)的閉包參數(shù)
  • 解決方案(三種)
    • weak var weakSelf = self
    • 在閉包的左花括號的右邊,參數(shù)類型的左邊 添加 [weak self],在閉包中訪問的self都是弱引用的,有可能為nil,所以self在閉包中是可選類型
    • 在閉包的左花括號的右邊,參數(shù)類型的左邊 添加 [unowned self],在閉包中訪問的self都是弱引用的,不可能可能為nil,所以self在閉包中是必選選類型

02-弱引用weak 和 unowned的區(qū)別

  • weak: 當(dāng)對象被系統(tǒng)回收時,地址會自動指向nil,為了防止野指針的問題
  • unowned: 和OC中的__unsafe_unretained解決方式一致,當(dāng)對象被系統(tǒng)回收的時候內(nèi)存地址不會制動指向nil
    func method2InSwift() {
        //解決方式3: [unowned self]
        //和OC中的__unsafe_unretained解決方式一致,當(dāng)對象被系統(tǒng)回收的時候內(nèi)存地址不會制動指向nil
        loadData(userName: "蕾蕾") { [unowned self] (res) in
            print("\(self)")
            
        }
    }
    
    
    func method1InSwift() {
        //解決方式2: [weak self]
        //當(dāng)對象被系統(tǒng)回收時,地址會自動指向nil,為了防止野指針的問題
        //和OC中 __weak解決方式的作用類似
        //
        loadData(userName: "蕾蕾") { [weak self] (res) in
            print("\(self)")
        }
    }
    
    
    func methodInOC() {
        //解決方式1: 仿照OC的解決方式
        weak var weakSelf = self
        loadData(userName: "蕾蕾") { (res) in
            print("\(weakSelf)")
        }
    }

03-構(gòu)造函數(shù)

  • super.init()作用
    • 對象的初始化時分段的,先初始化子類,確保子類的必選屬性有值,再調(diào)用super.init(),給父類中的必選屬性設(shè)置值
    • 標(biāo)記對象已經(jīng)初始化完畢,對象初始化完畢之后,才能夠調(diào)用對象的方法
  • override
    • 函數(shù)名相同,參數(shù)的個數(shù),或者參數(shù)類型不同就形成了函數(shù)的重載
  • 屬性和方法
    • 構(gòu)造函數(shù)必須確保必選屬性一定有初始值
    • 方法必須在對象構(gòu)造結(jié)束之后才可以調(diào)用

04-函數(shù)的重載

  • 概念
    • 函數(shù)名相同,參數(shù)的個數(shù),或者參數(shù)類型不同就形成了函數(shù)的重載,任意構(gòu)造函數(shù)都可以重載
    • 簡化程序員的記憶,只需要記住一個函數(shù)名即可,是面向?qū)ο蟮闹匾卣髦?br> OC沒有重載
  • 構(gòu)造函數(shù)重載特殊之處
    • 當(dāng)構(gòu)造函數(shù)發(fā)生了重載, 父類中沒有重寫的構(gòu)造函數(shù)都無法訪問
    • 如果構(gòu)造函數(shù)發(fā)生了重載,如果依然能夠訪問父類中的沒有重寫的構(gòu)造函數(shù),就會造成必選屬性 num 無法設(shè)置初始值
        //該函數(shù)是Student類中重載的構(gòu)造函數(shù)
        let s = Student(num: "007")
        
        //這兩個構(gòu)造函數(shù)是從Person中繼承的構(gòu)造函數(shù),并沒有實(shí)現(xiàn),此時是無法訪問的,編譯報錯
        let s1 = Student()
        let s2 = Student(name: "杜磊")

重載和重寫的對比,兩者之間沒有任何關(guān)系

  • override
    • 父類已經(jīng)存在的方法或者屬性,子類需要做特殊操作,在重寫的函數(shù)中可以super
  • overload
    • 函數(shù)名相同,參數(shù)的個數(shù),或者參數(shù)類型不同就形成了函數(shù)的重載

05-KVC構(gòu)造函數(shù)

  • 基本數(shù)據(jù)類型使用注意
    • 基本數(shù)據(jù)類型不能夠設(shè)置為可選類型
  • KVC執(zhí)行流程
    • 遍歷字典的鍵值對, 根據(jù)鍵 查找對象的屬性,就調(diào)用 setValue: forKey:
    • 在 setValue: forKey:方法中判斷屬性是否存在
    • 如果存在就直接根據(jù)鍵對應(yīng)的value設(shè)置值
    • 如果不存在就調(diào)用setValue: forUndeinedKey: 空實(shí)現(xiàn)

    init(dict: [String : Any]) {
        //KVC通過字典給對象的屬性賦值
        //KVC是一種間接的設(shè)置值的方式
        super.init()
        //遍歷字典的鍵值對, 根據(jù)鍵 查找對象的屬性
        //就調(diào)用 setValue: forKey:
        //在 setValue: forKey:方法中判斷屬性是否存在
        //如果存在就直接根據(jù)鍵對應(yīng)的value設(shè)置值
        //如果不存在就調(diào)用setValue: forUndeinedKey: 空實(shí)現(xiàn)
        self.setValuesForKeys(dict)
    }
    
    
    override func setValue(_ value: Any?, forKey key: String) {
        //OC中解決id的問題
        //        if ([key isEqualToStirng:@"id"]) {
        //            self.userId = value;
        //            //最好加上return
        //            return
        //        }
        super.setValue(value, forKey: key)
    }
    //重寫
    override func setValue(_ value: Any?, forUndefinedKey key: String) {
        //如果super 依然會報錯
        print(value,key)
    }

06-其他構(gòu)造函數(shù)

  • 可以返回nil

  • 便利構(gòu)造函數(shù)

    • 在本類中通過self調(diào)用指定的構(gòu)造函數(shù)
    • 也可以在子類中通過self訪問父類中指定的構(gòu)造函數(shù)
  • OC中的便利構(gòu)造函數(shù)

    • 在分類中增加構(gòu)造函數(shù)的時候不能夠使用super調(diào)用指定的構(gòu)造函數(shù),分類中沒有super
  • 使用場景

    • 在分類中增加構(gòu)造函數(shù)的時候需要使用到便利構(gòu)造函數(shù)
    //對構(gòu)造條件進(jìn)行檢查的時候可以使用可以返回nil的構(gòu)造函數(shù)
    convenience init?(name: String,age: Int) {
        
        if age < 0 || age > 200 {
            //條件不合法就不創(chuàng)建對象
            return nil
        }
        
        //滿足條件,就根據(jù)傳遞過來的參數(shù)創(chuàng)建對象
        //可以通過self來訪問本類中的指定的構(gòu)造函數(shù)
        //也可以在子類中通過self訪問父類中指定的構(gòu)造函數(shù)
        self.init(dict: ["name" : name, "age" : age])
        
    }
    
    //指定的構(gòu)造函數(shù)
    init(dict: [String : Any]) {
        super.init()
        self.setValuesForKeys(dict)
    }

07-懶加載

  • 作用和意義
    • 在使用的時候才會創(chuàng)建
    • 保證在使用的時候一定不為nil
    • 能夠讓代碼的格式更加規(guī)范
  • 關(guān)鍵字
    • lazy
  • 兩種格式
    //方式1: swift懶加載 lazy
    lazy var nameLabel1: UILabel = UILabel()
    
    //方式2
    //需要在初始化的時候設(shè)置文字和文字顏色
    //可以通過一個有返回值的閉包來完成label的初始化
    lazy var nameLabel: UILabel = { //() -> UILabel in 只有在懶加載中才可以省略這部分
        let l = UILabel()
        
        return l
    }()

08-get 和 set(newValue)

  • get 和 set 是可以成對出現(xiàn),也可以只有g(shù)et,但是get一定不能夠省略
    var _name: String?
    var name: String? {
        get {
            
            print("調(diào)用get")
            return _name
        }
        
        set {
            //在set的代碼塊中能夠訪問newValue
            _name = newValue
            print("調(diào)用set")
        }
    }

09-didSet(oldValue) 和 willSet(newValue)

    var name: String? {
     //可以訪問 newValue
     willSet {
            print(newValue)
            print("將要設(shè)置新值")
    }
     
    didSet {
            //可以訪問到oldValue
            print(oldValue)
            //可以訪問到已經(jīng)設(shè)置完的值
            print(name)
            print("已經(jīng)設(shè)置完成")
        }
    }

10-只讀屬性/計算型屬性/readOnly

  • 只實(shí)現(xiàn) get 代碼塊
    //方式1
    var title: String? {
        get {
            return "我的名字:\(name)"
        }
    }
    
    //方式2,省略get代碼塊, 是方式1的簡寫方式
    var title: String? {
        return "我的名字:\(name)"
    }
  • 計算性屬性: 依賴其他屬性進(jìn)行計算

    • 實(shí)現(xiàn)了 get 和 set
    • 或者只實(shí)現(xiàn)了get
  • 計算型屬性不占用內(nèi)存空間,每次執(zhí)行的時候都會調(diào)用,消耗cpu

  • 懶加載只調(diào)用一次,以后都是讀取內(nèi)存,消耗內(nèi)存,效率更高

11-錯誤處理的三種方式

  • try 默認(rèn)try 必須配合 do catch 來使用, 開發(fā)人員關(guān)注錯誤,并且需要對錯誤進(jìn)行處理
  • try? 可選try 如果沒有錯誤返回可選類型的結(jié)果,如果有錯 就返回nil,
  • try! 強(qiáng)行try 如果有錯 程序直接崩潰,如果沒喲錯誤返回的是必選類型的結(jié)果

    /*
    客戶端開發(fā)中很少使用默認(rèn)的try,會改變代碼的結(jié)構(gòu),在服務(wù)端開發(fā)中使用比較多
    根據(jù)請求選中 try? 或者 try!
    當(dāng)解析網(wǎng)絡(luò)請求的數(shù)據(jù)的時候可以使用 try?
    當(dāng)使用本地的數(shù)據(jù)的時候 可以使用強(qiáng)行的try!
    */

    //try 
    do {
        let json = try JSONSerialization.jsonObject(with: jsonData!, options: [])
        print(json)
    } catch {
        //可以捕捉錯誤 error只有在 catch對應(yīng)的代碼塊中才可以訪問
        print(error)
    }
    
    //try?
    let json = try? JSONSerialization.jsonObject(with: data!, options: [])
    print(json)
    
    //try!
    let json = try! JSONSerialization.jsonObject(with: data!, options: [])
    print(json)
    

12-項(xiàng)目

  • 項(xiàng)目名稱一定不要使用中文和數(shù)組組合,否則出現(xiàn)數(shù)組中無法添加元素
  • storyboard中使用自定義cell需要注意事項(xiàng)
tableView.dequeueReusableCell(withIdentifier: "DemoCellId", for: indexPath) 
這種方式獲取可重用cell的前提是先注冊cell,storyboard中只需要設(shè)置可重用標(biāo)識符和關(guān)聯(lián)類就已經(jīng)完成了注冊,不需要手動注冊

(tableView.register(PersonCell.self , forCellReuseIdentifier: "DemoCellId")),
如果添加手動注冊,就屬于畫蛇添足的步驟了,會導(dǎo)致注冊的是自定義類,此時只會調(diào)用cell的默認(rèn)構(gòu)造函數(shù):
init(style: UITableViewCellStyle, reuseIdentifier: String?),會導(dǎo)致storyboard中添加的自定義控件都無法實(shí)例化
  • as的使用
    • as 默認(rèn)轉(zhuǎn)換
        String(不是可選類型) -> NSString
        [類型](不是可選類型) -> NSArray
        [String : Any](不是可選類型) -> NSDictonary
  • as! 強(qiáng)行轉(zhuǎn)換
    • 強(qiáng)行將某一類型進(jìn)行轉(zhuǎn)換, 將父類類型的對象 轉(zhuǎn)換為子類類型的對象
    • 如果轉(zhuǎn)換不成功 程序就boom
    • 可以避免可選類型的問題
  • as? 可選轉(zhuǎn)換
    • 嘗試轉(zhuǎn)換 如果轉(zhuǎn)換失敗就為nil,如果轉(zhuǎn)換成功獲取結(jié)果是可選類型
    • 比較安全一些
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末辜羊,一起剝皮案震驚了整個濱河市房交,隨后出現(xiàn)的幾起案子北滥,更是在濱河造成了極大的恐慌,老刑警劉巖收班,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)娱俺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來废麻,“玉大人荠卷,你說我怎么就攤上這事≈蚶ⅲ” “怎么了油宜?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長怜姿。 經(jīng)常有香客問我慎冤,道長,這世上最難降的妖魔是什么沧卢? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任蚁堤,我火速辦了婚禮,結(jié)果婚禮上搏恤,老公的妹妹穿的比我還像新娘违寿。我一直安慰自己,他們只是感情好熟空,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布藤巢。 她就那樣靜靜地躺著,像睡著了一般息罗。 火紅的嫁衣襯著肌膚如雪掂咒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天迈喉,我揣著相機(jī)與錄音绍刮,去河邊找鬼。 笑死挨摸,一個胖子當(dāng)著我的面吹牛孩革,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播得运,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼膝蜈,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了熔掺?” 一聲冷哼從身側(cè)響起饱搏,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎置逻,沒想到半個月后推沸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年鬓催,在試婚紗的時候發(fā)現(xiàn)自己被綠了肺素。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡深浮,死狀恐怖压怠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情飞苇,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布蜗顽,位于F島的核電站布卡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏雇盖。R本人自食惡果不足惜忿等,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望崔挖。 院中可真熱鬧贸街,春花似錦、人聲如沸狸相。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽脓鹃。三九已至逸尖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瘸右,已是汗流浹背娇跟。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留太颤,地道東北人苞俘。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像龄章,于是被迫代替她去往敵國和親吃谣。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評論 2 351

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