Swift知識(shí)點(diǎn)(2)

1幌墓、as、as?、as!三種區(qū)別

as

  • 從派生類(lèi)轉(zhuǎn)換為基類(lèi)秕铛,向上轉(zhuǎn)型(upcasts)
  • 數(shù)值類(lèi)型(CGFloat, Int, Double)轉(zhuǎn)換
  • switch 語(yǔ)句中進(jìn)行模式匹配
switch person1 {
    case let person1 as Student:
        print("是Student類(lèi)型,打印學(xué)生成績(jī)單...")
    case let person1 as Teacher:
        print("是Teacher類(lèi)型缩挑,打印老師工資單...")
    default: break
}

as!
向下轉(zhuǎn)型(Downcasting, 基類(lèi)轉(zhuǎn)換為派生類(lèi))時(shí)使用但两。由于是強(qiáng)制類(lèi)型轉(zhuǎn)換,如果轉(zhuǎn)換失敗會(huì)報(bào) runtime 運(yùn)行錯(cuò)誤供置。
as?
as? 和 as! 操作符的轉(zhuǎn)換規(guī)則完全一樣谨湘。但 as? 如果轉(zhuǎn)換不成功的時(shí)候便會(huì)返回一個(gè) nil 對(duì)象。成功的話返回可選類(lèi)型值芥丧。由于 as? 在轉(zhuǎn)換失敗的時(shí)候也不會(huì)出現(xiàn)錯(cuò)誤紧阔,所以對(duì)于如果能確保100%會(huì)成功的轉(zhuǎn)換則可使用 as!,否則使用 as?

2续担、便利構(gòu)造函數(shù)

示例:

convenience init(imageName: String, bgImageName: String){  
        self.init() 
        setImage(UIImage(named:imageName), for: .normal)   
    }  

使用convenience修飾的構(gòu)造函數(shù)叫做便利構(gòu)造函數(shù)
便利構(gòu)造函數(shù)通常用在對(duì)系統(tǒng)的類(lèi)進(jìn)行構(gòu)造函數(shù)的擴(kuò)充時(shí)使用擅耽。

  • 便利構(gòu)造函數(shù)通常都是寫(xiě)在extension里面(也可用在類(lèi)中)
  • 便利函數(shù)init前面需要加載convenience
  • 在便利構(gòu)造函數(shù)中需要明確的調(diào)用self.init()

3、private(set)

private(set)將set方法的訪問(wèn)級(jí)別降低物遇,低于get訪問(wèn)級(jí)別乖仇,set方法只有在該模塊中調(diào)用憾儒,對(duì)外是只讀的。
示例:

public private(set) lazy var name: String = {
        return "hello";
 }()

4乃沙、Swift和OC混編

  • 在OC項(xiàng)目中創(chuàng)建一個(gè)swift文件的時(shí)候起趾,Xcode 會(huì)提示 需要?jiǎng)?chuàng)建一個(gè)橋接文件,其名字為:工程名-Bridging-Header.h
  • 進(jìn)入TARGETS ->Build Settings -> Packaging 中設(shè)置Defines Module為YES警儒。
  • Objective-C Bridging Header中設(shè)置橋接文件训裆,路徑為:工程名/工程名-Bridging-Header.h
  • OC調(diào)用Swift時(shí),在OC文件中導(dǎo)入 #import “工程名-Swift.h”冷蚂,就可以調(diào)用Swift的代碼了缭保。
  • Swift調(diào)用OC時(shí),需要將要調(diào)用的OC頭文件導(dǎo)入到橋接文件中蝙茶,就能調(diào)用了艺骂。
    注意:最好每一步操作前comman+B編譯一下,看是否報(bào)錯(cuò)隆夯。

5钳恕、NS_ASSUME_NONNULL_BEGIN & NS_ASSUME_NONNULL_END

Swift中的對(duì)象使用 ? 和 ! 可以分為可選和不可選,OC里面沒(méi)有這個(gè)區(qū)分蹄衷,導(dǎo)致OC和Swift混編的時(shí)候忧额,Swift不知道一個(gè)Objective-C對(duì)象到底是optional還是non-optional,因此這種情況下編譯器會(huì)隱式地將Objective-C的對(duì)象當(dāng)成是non-optional愧口。
為了解決這個(gè)問(wèn)題睦番,蘋(píng)果在Xcode 6.3引入了一個(gè)Objective-C的新特性:nullability annotations。這一新特性的核心是兩個(gè)新的類(lèi)型注釋: __nullable 和 __nonnull耍属,如果需要每個(gè)屬性或每個(gè)方法都去指定nonnull和nullable托嚣,是一件非常繁瑣的事。蘋(píng)果為了減輕我們的工作量厚骗,專門(mén)提供了兩個(gè)宏:NS_ASSUME_NONNULL_BEGIN示启, NS_ASSUME_NONNULL_END。在這兩個(gè)宏之間的代碼领舰,所有簡(jiǎn)單指針對(duì)象都被假定為nonnull夫嗓,因此我們只需要去指定那些nullable的指針。

NS_ASSUME_NONNULL_BEGIN
@interface TestObject : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic) BOOL isOpen;

- (void)setDataAccessDate:(NSDate*)date forRequestWithIdentifier:(NSString* _Nullable)identifier;

@end
NS_ASSUME_NONNULL_END

6冲秽、Switch語(yǔ)句

Swift中Switch語(yǔ)句不需要在每個(gè)case后面加break舍咖,會(huì)自動(dòng)跳出不執(zhí)行后面的case,如果想按順序執(zhí)行下面的case锉桑,可以加上fallthrough語(yǔ)句谎仲。

7、可失敗構(gòu)造器

如果一個(gè)類(lèi)刨仑,結(jié)構(gòu)體或枚舉類(lèi)型的對(duì)象郑诺,在構(gòu)造自身的過(guò)程中有可能失敗,則為其定義一個(gè)可失敗構(gòu)造器杉武。使用 init? 的方法辙诞,當(dāng)返回nil的時(shí)候表示構(gòu)造失敗。

struct Animal {
    let species: String
    init?(species: String) {
        if species.isEmpty { return nil }
        self.species = species
    }
}

8轻抱、try try? try! 的區(qū)別

發(fā)生異常的時(shí)候的三種處理方式:

  • try:發(fā)生異常處理異常
do {
    var str = try testFunc(str: "three")
} catch {
    print(“error”)
}
  • try?: 如果不想處理異常那么可以用這個(gè)關(guān)鍵字,使用這個(gè)關(guān)鍵字返回一個(gè)可選值類(lèi)型,如果有異常出現(xiàn),返回nil.如果沒(méi)有異常,則返回可選值
var str = try? testFunc(str: "three")
  • try!:如果不想處理異常,而且不想讓異常繼續(xù)傳播下去,可以使用try!.這有點(diǎn)兒類(lèi)似NSAssert().但是一旦使用try!后,在可能拋出異常的方法中拋出了異常,那么程序會(huì)立刻停止.不推薦使用飞涂。
var str = try! testFunc(str: "three")

9、逃逸閉包和非逃逸閉包

閉包只有在函數(shù)中做參數(shù)時(shí)才會(huì)區(qū)分逃逸閉包和非逃逸閉包祈搜。
Swift 3.0之后较店,傳遞閉包到函數(shù)中的時(shí)候,系統(tǒng)會(huì)默認(rèn)為非逃逸閉包類(lèi)型@noescaping容燕,逃逸閉包在閉包前要添加@escaping關(guān)鍵字梁呈。
兩者生命周期的區(qū)別:
非逃逸閉包的生命周期與函數(shù)相同:

  • 把閉包作為參數(shù)傳給函數(shù);
  • 函數(shù)中調(diào)用閉包蘸秘;
  • 退出函數(shù)官卡。結(jié)束

逃逸閉包的生命周期:

  • 閉包作為參數(shù)傳遞給函數(shù);
  • 退出函數(shù)醋虏;
  • 閉包被調(diào)用寻咒,閉包生命周期結(jié)束
    即逃逸閉包的生命周期長(zhǎng)于函數(shù),函數(shù)退出的時(shí)候颈嚼,逃逸閉包的引用仍被其他對(duì)象持有毛秘,不會(huì)在函數(shù)結(jié)束時(shí)釋放
    逃逸閉包示例:
//ClassDetailsDAO.swift
func enrollToClass(classUUID: String, spot: String?, completion: @escaping (Result<ClassData>) -> Void) {
        guard let calendarEntry = model.calendarEntry(withUUID: classUUID, createNew: false) else {
            completion(.failure(ClassDetailsDAOError.entryNotFound))
            return
        }
    }

逃逸閉包一般使用的場(chǎng)景:網(wǎng)絡(luò)請(qǐng)求請(qǐng)求結(jié)束后才調(diào)用的閉包,因?yàn)榘l(fā)起請(qǐng)求后過(guò)了一段時(shí)間后這個(gè)閉包才執(zhí)行阻课,并不一定是在函數(shù)作用域內(nèi)執(zhí)行叫挟。

循環(huán)引用

非逃逸閉包不會(huì)產(chǎn)生循環(huán)引用,它會(huì)在函數(shù)作用域內(nèi)釋放柑肴,編譯器可以保證在函數(shù)結(jié)束時(shí)閉包會(huì)釋放它捕獲的所有對(duì)象霞揉。
逃逸閉包會(huì)產(chǎn)生循環(huán)引用的問(wèn)題,為了解決循環(huán)引用問(wèn)題晰骑,使用[weak self]

classDetailsDAO.enrollToClass(classUUID: classUUID, spot: spot) { [weak self] (result) in
         guard let strongSelf = self else {
             return
         }

         switch result {
         case .success(let classData):
             strongSelf.presenter.didEnrollToClass(classData: classData)
         case .failure(let error):
             strongSelf.presenter.didFailToEnrollToClass(error: error)
        }
}

10适秩、Any和AnyObject

  • 有點(diǎn)類(lèi)似OC中的id,Swift為不確定的類(lèi)型硕舆,提供了兩種特殊別名秽荞,any和anyobject,
  • AnyObject可以表示class類(lèi)型的實(shí)例抚官。
  • Any可以表示任何類(lèi)型的實(shí)例扬跋。

11、String(describing:)

獲取類(lèi)名稱的字符串

class Foo {

    // 實(shí)例屬性中指定明確的類(lèi)名來(lái)獲取名稱
    var typeName: String {
        return String(describing: Foo.self)
    }

    // 實(shí)例屬性中動(dòng)態(tài)獲取類(lèi)名來(lái)獲取名稱
    var otherTypeName: String {
        let thisType = type(of: self)
        return String(describing: thisType)
    }

    // 類(lèi)屬性中直接獲取名稱
    static var typeName: String {
        return String(describing: self)
    }

}

Foo().typeName       // = "Foo"
Foo().otherTypeName  // = "Foo"
Foo.typeName         // = "Foo"

12凌节、defer的使用

Swift2.0中加入了defer新語(yǔ)法聲明钦听,defer譯為延緩洒试、推遲之意。
使用場(chǎng)景:
比如朴上,讀取某目錄下的文件內(nèi)容并處理數(shù)據(jù)垒棋,你需要首先定位到文件目錄,打開(kāi)文件夾痪宰,讀取文件內(nèi)容以及處理數(shù)據(jù)叼架,在讀取文件內(nèi)容失敗、處理數(shù)據(jù)失敗的情況下要關(guān)閉文件的操作衣撬,在讀取成功的情況下最后也要關(guān)閉文件的操作乖订,這個(gè)時(shí)候可以把關(guān)閉文件的代碼放到defer中來(lái)延遲執(zhí)行。
所以具练,defer{}中的代碼會(huì)在作用域結(jié)束之前或者說(shuō)return之前最后調(diào)用
例子:

func fridgeContains(_ food: String) -> Bool {
    fridgeIsOpen = true
    defer {
        //最后調(diào)用
        fridgeIsOpen = false
    }
    
    let result = fridgeContent.contains(food)
    return result
}

13乍构、@discardableResult的作用

@discardableResult func doSomething() -> Bool {
  return true
}

例如上面的方法,如果使用 doSomething() 調(diào)用該函數(shù)靠粪,但是沒(méi)有用變量來(lái)接收函數(shù)的返回參數(shù)時(shí)蜡吧,就會(huì)報(bào)警告,這時(shí)候@discardableResult來(lái)消除警告占键。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末昔善,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子畔乙,更是在濱河造成了極大的恐慌君仆,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件牲距,死亡現(xiàn)場(chǎng)離奇詭異返咱,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)牍鞠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)咖摹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人难述,你說(shuō)我怎么就攤上這事萤晴。” “怎么了胁后?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵店读,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我攀芯,道長(zhǎng)屯断,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮殖演,結(jié)果婚禮上氧秘,老公的妹妹穿的比我還像新娘。我一直安慰自己剃氧,他們只是感情好敏储,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著朋鞍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪妥箕。 梳的紋絲不亂的頭發(fā)上滥酥,一...
    開(kāi)封第一講書(shū)人閱讀 52,394評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音畦幢,去河邊找鬼坎吻。 笑死,一個(gè)胖子當(dāng)著我的面吹牛宇葱,可吹牛的內(nèi)容都是我干的瘦真。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼黍瞧,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼诸尽!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起印颤,我...
    開(kāi)封第一講書(shū)人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤您机,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后年局,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體际看,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年矢否,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了仲闽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡僵朗,死狀恐怖赖欣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情衣迷,我是刑警寧澤畏鼓,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站壶谒,受9級(jí)特大地震影響云矫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜汗菜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一让禀、第九天 我趴在偏房一處隱蔽的房頂上張望挑社。 院中可真熱鬧,春花似錦巡揍、人聲如沸痛阻。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)阱当。三九已至,卻和暖如春糜工,著一層夾襖步出監(jiān)牢的瞬間弊添,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工捌木, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留油坝,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓刨裆,卻偏偏與公主長(zhǎng)得像澈圈,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子帆啃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359