Swift3.0學(xué)習(xí)筆記(二)

寫(xiě)在前面

這是我學(xué)習(xí)Swift3.0的學(xué)習(xí)筆記系列的第二篇文章扔罪,本篇同第一篇一樣始腾,將主要介紹Swift的一些基礎(chǔ)語(yǔ)法,包括控制流呕寝、閉包等內(nèi)容勋眯。由于本人水平有限,接觸Swift語(yǔ)言的時(shí)間也只有一個(gè)月左右下梢,所以文中有些描述的不準(zhǔn)確客蹋,甚至是錯(cuò)誤的觀點(diǎn),還望各路大神能夠不吝賜教孽江,幫我指出讶坯。我原來(lái)一直使用Objective-C語(yǔ)言進(jìn)行iOS的開(kāi)發(fā),出于對(duì)新知識(shí)的好奇與渴望岗屏,才開(kāi)始自學(xué)Swift闽巩,但剛開(kāi)始的時(shí)候钧舌,遇到了很多問(wèn)題,網(wǎng)上檢索資料涎跨,發(fā)現(xiàn)目前Swift3.0的學(xué)習(xí)資料比較少洼冻,大部分都是之前版本的,由于3.0較之前版本在某些部分的改動(dòng)還較大隅很,感覺(jué)缺少資料的學(xué)習(xí)還是比較吃力的撞牢,如果你也像我一樣,是剛從OC轉(zhuǎn)向Swift的叔营,并且一開(kāi)始就接觸的是Swift3.0屋彪,那么我的學(xué)習(xí)筆記也許會(huì)對(duì)你有些許幫助。另外绒尊,我有個(gè)和大家一起討論Swift3.0學(xué)習(xí)的技術(shù)交流群185826825畜挥,歡迎大家來(lái)與我們共同學(xué)習(xí)!我的本系列其它文章:
Swift3.0學(xué)習(xí)筆記(一)


  • 控制流

  1. if else

眾所周知婴谱,Swift沒(méi)有了麻煩的;作為句尾結(jié)束符蟹但,那么對(duì)于簡(jiǎn)單的條件判斷我們干脆也就不用()了,現(xiàn)在谭羔,你可以像這樣寫(xiě)一個(gè)if else

let a = 3, b = 2
if a > b {
       print("a>b的條件為真")
} else {
       print("a>b的條件為假")
}

如果是比較復(fù)雜的條件华糖,你仍需要加上(),來(lái)說(shuō)明條件都包括什么:

let a = 3, b = 2, c = 4, d = 1
let condition_1 = a > b
let condition_2 = c < d
if (condition_1 || condition_2) {
       print("條件1為真或者條件2為真")
}

我們?cè)陂_(kāi)發(fā)中瘟裸,經(jīng)常會(huì)判斷一個(gè)對(duì)象是否為nil客叉,在Swift中我們可以這樣做:

let image: UIImage? = UIImage.init(named: "abc")
if let image = image {
       print("我們拿到image的內(nèi)容了")
} else {
       print("我們拿到的image為nil")
}

此時(shí)如果運(yùn)行后,在MainBundle中沒(méi)有abc.png這個(gè)文件的話话告,控制臺(tái)則會(huì)輸出我們拿到的image為nil兼搏。在條件判斷時(shí),我們使用了Swift中的if let語(yǔ)法沙郭,它的含義是佛呻,我們重新定義一個(gè)常量,使用一個(gè)可選類型的值給這個(gè)常量進(jìn)行賦值棠绘,如果賦值后件相,這個(gè)可選類型的值是nil的話再扭,也就相當(dāng)于我們?cè)谑褂?code>if image == nil去進(jìn)行判斷氧苍,需要注意的是,新定義的這個(gè)image只能在if{}內(nèi)訪問(wèn)泛范。

  1. guard else

同剛才那個(gè)案例一樣让虐,我們經(jīng)常會(huì)做一些對(duì)象是否為nil的判斷,事實(shí)上罢荡,我們只會(huì)在對(duì)象不為nil的時(shí)候才會(huì)去做一些邏輯赡突,而當(dāng)對(duì)象真的是nil的時(shí)候对扶,我們也許什么也不做,如果能夠?qū)ξ覀儾黄谕慕Y(jié)果早做檢查惭缰,會(huì)使我們的代碼更加貼近我們想要實(shí)現(xiàn)的目的浪南,并且讓它看起來(lái)更容易理解。guard else就是來(lái)做這件事的漱受,從字面的意思來(lái)看络凿,保證,除此之外確實(shí)很容易理解昂羡,那么就讓我們看看這個(gè)語(yǔ)法該怎么使用吧絮记,比如我有一個(gè)用于接收消息的函數(shù),需求是只對(duì)消息內(nèi)容中含有'abc'的內(nèi)容作處理虐先,代碼如下:

func didReceivedMessage(msg: String) {
         guard msg.contains("abc") else { return }
         print("消息中包含字符串a(chǎn)bc怨愤,我需要做處理了")
}

這里需要注意,在else中一定需要加上return蛹批,如果是在循環(huán)內(nèi)或switch中可以加break撰洗,用以結(jié)束這個(gè)函數(shù),不加的話編譯不能通過(guò)般眉。
if let語(yǔ)法類似的了赵,guard else也有guard let else的用法。

  1. switch

和OC的switch相比甸赃,swift的switch語(yǔ)句強(qiáng)大了很多柿汛,用法也更靈活。首先埠对,switch不再只能檢查整型類型的值络断,它還能檢查浮點(diǎn)型、布爾類型项玛、字符串貌笨、元組等,同時(shí)襟沮,每個(gè)case默認(rèn)都會(huì)有一個(gè)break锥惋,因此你不再額外需要寫(xiě)break關(guān)鍵字了;每個(gè)case下的代碼塊也不需要{}來(lái)進(jìn)行整理开伏,只需要將代碼寫(xiě)在兩個(gè)case之間就好膀跌;每個(gè)switch語(yǔ)句必須涵蓋所有的條件,不能夠像OC那樣只寫(xiě)一兩個(gè)你關(guān)注的條件固灵,剩余你不想關(guān)注的條件可以使用default: break來(lái)補(bǔ)充捅伤;default關(guān)鍵字不能出現(xiàn)在case的前面。
switch中還增加了一個(gè)有意思的用法巫玻,值綁定丛忆。所謂值綁定就是你可以在case分?里將匹配的值綁定到?個(gè)臨時(shí)的常量或變量祠汇,這個(gè)常量或變量在該case分??就可以被引?了:

switch "abc123" {
case let x where x.hasSuffix("123"):
       print("x = \(x)")
default: break
}

控制臺(tái)輸出abc123,代碼中的let x就是將匹配到的值賦值給常量x熄诡,where就是對(duì)被匹配的對(duì)象進(jìn)行篩選可很,使得滿足條件的被匹配對(duì)象才能進(jìn)入case。
switch用來(lái)匹配元組凰浮,就像這樣:

let point = (2, 0)
switch point {
    case (let x, 0):
        print("點(diǎn)在x軸上根穷,橫坐標(biāo)為\(x)")
    case (0, let y):
        print("點(diǎn)在y軸上,縱坐標(biāo)為 \(y)")
    case let (x, y): //匹配所有
        print("點(diǎn)不在坐標(biāo)軸上导坟,該點(diǎn)坐標(biāo)是(\(x), \(y))")
}

  • 循環(huán)

循環(huán)語(yǔ)句和OC的循環(huán)類似屿良,大概有for循環(huán)和while循環(huán)幾種,對(duì)于for循環(huán)來(lái)說(shuō)惫周,swift取消了C語(yǔ)言風(fēng)格的for (int i = 0; i < 10; i++)語(yǔ)法尘惧,取而代之的是這樣for i in 0..<10,如果你不需要i作為循環(huán)次數(shù)的索引递递,你可以這樣寫(xiě)for _ in 0..<10喷橙,使用一個(gè)下劃線_來(lái)省略。你也可以使用for in對(duì)某個(gè)數(shù)組進(jìn)行遍歷登舞,像這樣:

let arr = Array.init(repeating: "abc", count: 3)
for str in arr {
    print(str)
}

控制臺(tái)輸出:

abc
abc
abc

  • 數(shù)組

在Swift中贰逾,取消了NS的前綴,我們可以直接定義一個(gè)Array類型的變量或常量菠秒,但前提是我必須指定存放在數(shù)組中元素的類型疙剑,對(duì)于未知的類型我們可以使用Any來(lái)表示,像這樣:

let array: Array<Any> = [("" as Any)]

我們聲明了一個(gè)不可變數(shù)組践叠,其中有一個(gè)元素言缤,是一個(gè)空字符串,由于類型安全禁灼,我們需要將這個(gè)字符串類型的元素轉(zhuǎn)換為Any類型管挟。
如果改為var類型,則該數(shù)組為可變數(shù)組弄捕,可以使用添加僻孝、刪除等函數(shù)對(duì)該數(shù)組進(jìn)行修改:

var array: Array<String> = [""]
array.append("abc")
array.remove(at: 0)

  • 字典

同數(shù)組一樣,聲明時(shí)需要指定字典的key-value的數(shù)據(jù)類型守谓,比如:

var dict = Dictionary<String, Int>()
dict["abc"] = 123

在Swift中穿铆,沒(méi)有了.h.m文件,取而代之的是一個(gè).swift文件分飞,在.swift文件中使用publicprivate關(guān)鍵字來(lái)區(qū)別函數(shù)和屬性的公開(kāi)和私有悴务,對(duì)于沒(méi)有添加這個(gè)關(guān)鍵字的函數(shù)和屬性睹限,在swift中默認(rèn)是公開(kāi)的譬猫。對(duì)于繼承讯檐,swift仍延續(xù)了使用:來(lái)表示繼承關(guān)系,而之后染服,我們可以方便地使用","對(duì)要繼承的父類進(jìn)行分割别洪,在后面添加上我們要遵守的協(xié)議,這看起來(lái)就像這樣:

  • 懶加載

我們?cè)趕wift中可以在聲明屬性的時(shí)候柳刮,用懶加載的方式進(jìn)行聲明挖垛,這樣類似OC,可以在只有訪問(wèn)這個(gè)屬性的時(shí)候才在內(nèi)存開(kāi)辟空間秉颗。比如這樣:

lazy private var placeHolderLabel: UILabel = {
        let tempLabel = UILabel()
        return tempLabel
    }()

  • 屬性監(jiān)聽(tīng)

我們可以使用Swift提供給我們的屬性觀察器痢毒,獲取到屬性被賦值前和被賦值后的時(shí)機(jī),像這樣:

    private var x: Int = 0 {
        willSet {
            print("當(dāng)前值 = \(x)")
            print("將被賦予的新值 = \(newValue)")
        }
        didSet {
            print("當(dāng)前值 = \(x)")
            print("被賦新值之前的舊值 = \(oldValue)")
        }
    }

其中在willSet方法中提供了一個(gè)值newValue蚕甥,用來(lái)訪問(wèn)這個(gè)屬性要被賦的新值哪替,在didSet方法中提供了一個(gè)oldValue用來(lái)訪問(wèn)被賦值之前的舊值,這這兩個(gè)方法中我們都可以使用屬性本身來(lái)訪問(wèn)當(dāng)前的值」交常現(xiàn)在我們讓x = 1凭舶,可以看到控制臺(tái)輸出:

當(dāng)前值 = 0
將被賦予的新值 = 1
當(dāng)前值 = 1
被賦新值之前的舊值 = 0

  • 函數(shù)

swift中,函數(shù)使用關(guān)鍵字func作為函數(shù)的開(kāi)始爱沟,緊接著后面是函數(shù)名帅霜,不同于OC的風(fēng)格,swift不再將函數(shù)名和參數(shù)混在一起寫(xiě)呼伸,而是將所有的參數(shù)都使用()括起來(lái)身冀,之后使用一個(gè)->符號(hào)來(lái)表示此函數(shù)的返回類型,在這個(gè)符號(hào)的后面寫(xiě)上返回類型括享,就像這樣:

func login(userName: String, password: String) -> Bool {
    if (userName == "abc" && password == "123") {
       return true
    }
    return false
}

我們都知道在OC中有類方法和實(shí)例方法的區(qū)別闽铐,在Swift中,如果在func關(guān)鍵字前增加class關(guān)鍵字奶浦,則該方法為類方法兄墅,否則默認(rèn)都是實(shí)例方法“牟妫可以看到隙咸,剛才我們寫(xiě)的那個(gè)login的函數(shù)就是一個(gè)實(shí)例方法,我們調(diào)用這個(gè)函數(shù)的方式同OC一樣成洗,首先要有這個(gè)函數(shù)所在類的實(shí)例五督,然后使用實(shí)例對(duì)象去調(diào)用這個(gè)方法,在Swift中瓶殃,不再像OC一樣使用方括號(hào)+空格的方式去向?qū)ο蟀l(fā)消息充包,而是直接使用點(diǎn)語(yǔ)法,假設(shè)這個(gè)函數(shù)在某個(gè)類中,我們這樣調(diào)用該函數(shù):

let isSuccess = self.login(userName: "abc", password: "123")

在這個(gè)函數(shù)中基矮,userNamepassword是函數(shù)的形參淆储,是函數(shù)的內(nèi)部參數(shù)名,那么對(duì)應(yīng)的家浇,什么是函數(shù)的實(shí)參外部參數(shù)名呢本砰?我們?cè)谡{(diào)用這個(gè)函數(shù)時(shí),在輸入?yún)?shù)的地方钢悲,我們輸入的參數(shù)就是這個(gè)函數(shù)的實(shí)參点额,對(duì)于外部參數(shù)名即是指我們?cè)诤瘮?shù)調(diào)用時(shí)所看到的參數(shù)名,其寫(xiě)法是在內(nèi)部參數(shù)名的前面使用一個(gè)空格來(lái)分割莺琳,并在前面寫(xiě)上參數(shù)名还棱,比如func inputUserName(用戶名 userName: String) -> Void,這樣我們?cè)谡{(diào)用這個(gè)函數(shù)時(shí)就是這個(gè)樣子的:

self.inputUserName(用戶名: "abc")

如果我們沒(méi)有刻意去寫(xiě)外部參數(shù)名惭等,那么在調(diào)用函數(shù)時(shí)會(huì)默認(rèn)該函數(shù)的外部參數(shù)名內(nèi)部參數(shù)名一致诱贿,那么如果我們不希望在調(diào)用時(shí)看到這個(gè)函數(shù)的外部參數(shù)名該怎么辦呢?像剛才那個(gè)登錄的函數(shù)咕缎,我們可以使用這樣的方式對(duì)外部參數(shù)名進(jìn)行省略:

//注意:函數(shù)的返回值如果是空的話珠十,可以寫(xiě)(),或者Void
//或者直接省略這些: "-> ()"凭豪,即參數(shù)后面直接接函數(shù)體
func login(_ userName: String, _ password: String) -> () {
    if (userName == "abc" && password == "123") {
       return true
    }
    return false
}
//函數(shù)調(diào)用
self.login("abc", "123")

另外焙蹭,我們還可以給函數(shù)的參數(shù)一個(gè)默認(rèn)值,比如:

func showMsg(msg: String? = "hello") {
        print(msg)
}
self.showMessage()

控制臺(tái)輸出Optional("hello")

  • 閉包

閉包其實(shí)類似OC中的Block嫂伞,是一段代碼塊孔厉,可以像函數(shù)一樣實(shí)現(xiàn)某些功能,也可以作為參數(shù)進(jìn)行傳遞帖努,可以看成是匿名函數(shù)撰豺。
閉包的語(yǔ)法:

{(參數(shù)名) -> 返回類型 in 
    代碼塊
}
//對(duì)比OC的寫(xiě)法
返回類型(^bolck名)(參數(shù)類型及參數(shù)名) {
    代碼塊
}

在網(wǎng)上關(guān)于Swift的閉包有比較多的介紹,在此向大家推薦一個(gè)網(wǎng)址來(lái)學(xué)習(xí):Swift教程-閉包
在此舉一個(gè)簡(jiǎn)單的例子拼余,簡(jiǎn)單封裝一下網(wǎng)絡(luò)請(qǐng)求方式:

class func get(url: String, parameters: Dictionary<String, AnyObject>? = nil, 
completionHandler: @escaping (_ response: DataResponse<Data>) -> ()) {
        Alamofire.request(url, method: .get, parameters: parameters, encoding: URLEncoding.default, headers: nil)
                 .responseData { (response) in
                     completionHandler(response)
        }
 }

細(xì)心的你會(huì)發(fā)現(xiàn)在completionHandler這個(gè)閉包中有個(gè)@escaping關(guān)鍵字污桦,字面意思是逃逸,那么什么是逃逸呢匙监?又是否有與之對(duì)應(yīng)的類似不可逃逸的關(guān)鍵字呢凡橱?

  1. 逃逸閉包

當(dāng)我們?cè)谶M(jìn)行網(wǎng)絡(luò)請(qǐng)求時(shí),由于是異步操作亭姥,所以在函數(shù)返回時(shí)稼钩,閉包中的內(nèi)容可能還沒(méi)有被觸發(fā),所以要求閉包的生命周期能夠長(zhǎng)于函數(shù)本身达罗,也就是讓閉包能夠逃出函數(shù)存在坝撑,這就是逃逸閉包,在函數(shù)聲明時(shí),在閉包前使用@escaping關(guān)鍵字巡李。

  1. 非逃逸閉包

對(duì)于某些函數(shù)抚笔,例如Swift數(shù)組中的map函數(shù),其作用是將給定數(shù)組復(fù)制出來(lái)一份副本击儡,并根據(jù)你寫(xiě)的map規(guī)則將此副本映射成一個(gè)新的數(shù)組,對(duì)于這樣執(zhí)行同步操作的函數(shù)蝠引,在函數(shù)執(zhí)行完成之后阳谍,就不再需要此閉包繼續(xù)存在了,可以使用非逃逸閉包螃概,其關(guān)鍵字是@noescape矫夯。

 let arr = ["a", "b"]
let newArr = arr.map { (originalValue) -> String in
            return "字母" + originalValue
        }
print(newArr)

控制臺(tái)輸出["字母a", "字母b"]

  1. 參數(shù)名縮寫(xiě)

Swift為閉包提供了參數(shù)名的縮寫(xiě)功能吊洼,我們可以直接使用$0, $1, $2來(lái)順序訪問(wèn)閉包內(nèi)的參數(shù)训貌,上面那個(gè)例子我們就可以簡(jiǎn)寫(xiě)成這樣:

let arr = ["a", "b"]
let newArr = arr.map({ "字母" + $0 })

  • 構(gòu)造器

所謂構(gòu)造器,就是我們可以通過(guò)這個(gè)構(gòu)造器來(lái)構(gòu)造一個(gè)類的實(shí)例冒窍。在OC中递沪,我們使用init函數(shù)來(lái)對(duì)類進(jìn)行實(shí)例化操作,在Swift中综液,我們有兩種構(gòu)造方式款慨,指定構(gòu)造器和遍歷構(gòu)造器。關(guān)于構(gòu)造器的介紹谬莹,我引用了Draveness的文章Swift 類構(gòu)造器的使用檩奠,文章介紹的很詳細(xì)。

  1. 指定構(gòu)造器designated initialize

指定構(gòu)造器是類的主要構(gòu)造器附帽,要在指定構(gòu)造器中初始化所有的屬性埠戳,并且要在調(diào)用父類合適的指定構(gòu)造器。每個(gè)類應(yīng)該只有少量的指定構(gòu)造器蕉扮,大多數(shù)類只有一個(gè)指定構(gòu)造器整胃,我們使用 Swift 做 iOS 開(kāi)發(fā)時(shí)就會(huì)用到很多UIKit框架類的指定構(gòu)造器, 比如說(shuō):

init()  
init(frame: CGRect)  
init(style: UITableViewCellStyle, reuseIdentifier: String?)

當(dāng)定義一個(gè)指定構(gòu)造器的時(shí)候, 必須調(diào)用父類的某一個(gè)指定構(gòu)造器:

init(imageName: String, prompt: String = "") {  
         super.init(style: .Default, reuseIdentifier: nil)
}
  1. 便利構(gòu)造器convenience initialize

便利構(gòu)造器是類的次要構(gòu)造器, 你需要讓便利構(gòu)造器調(diào)用同一個(gè)類中的指定構(gòu)造器, 并將這個(gè)指定構(gòu)造器中的參數(shù)填上你想要的默認(rèn)參數(shù)。
如果你的類不需要便利構(gòu)造器的話喳钟,那么你就不必定義便利構(gòu)造器, 便利構(gòu)造器前面必須加上convenience關(guān)鍵字爪模。
在這里我們就不舉例了, 但是我們要提一下便利構(gòu)造器的語(yǔ)法:

    convenience init(name: String?, user_id: String?) {
        self.init()
        self.name = name
        self.user_id = user_id
    }

其中調(diào)用self.init()時(shí),相當(dāng)于調(diào)用類的designated initialize方法荚藻,即調(diào)用ClassName(),該類中所有的變量都會(huì)被使用默認(rèn)值進(jìn)行初始化屋灌。

  1. init規(guī)則

定義 init 方法必須遵循三條規(guī)則:

  • 指定構(gòu)造器必須調(diào)用它直接父類的指定構(gòu)造器方法。
  • 便利構(gòu)造器必須調(diào)用同一個(gè)類中定義的其它初始化方法应狱。
  • 便利構(gòu)造器在最后必須調(diào)用一個(gè)指定構(gòu)造器共郭。

    只有指定構(gòu)造器才可以調(diào)用父類的指定構(gòu)造器,而便利構(gòu)造器是不可以的,這也遵循了這的三條規(guī)則除嘹。

  1. init 的繼承和重載

跟 OC 不同写半,Swift 中的子類默認(rèn)不會(huì)繼承來(lái)自父類的所有構(gòu)造器。這樣可以防止錯(cuò)誤的繼承并使用父類的構(gòu)造器生成錯(cuò)誤的實(shí)例(可能導(dǎo)致子類中的屬性沒(méi)有被賦值而正確初始化)尉咕。與方法不同的一點(diǎn)是, 在重載構(gòu)造器的時(shí)候, 你不需要添加override關(guān)鍵字叠蝇。
雖然子類不會(huì)默認(rèn)繼承來(lái)自父類的構(gòu)造器,但是我們也可以通過(guò)別的方法來(lái)自動(dòng)繼承來(lái)自父類的構(gòu)造器年缎,構(gòu)造器的繼承就遵循以下的規(guī)則:

  • 如果子類沒(méi)有定義任何的指定構(gòu)造器悔捶,那么會(huì)默認(rèn)繼承所有來(lái)自父類的指定構(gòu)造器。
  • 如果子類提供了所有父類指定構(gòu)造器的實(shí)現(xiàn)单芜,不管是通過(guò)上面的規(guī)則繼承過(guò)來(lái)的蜕该,還是通過(guò)自定義實(shí)現(xiàn)的,它將自動(dòng)繼承所有父類的便利構(gòu)造器洲鸠。
  1. 構(gòu)造器總結(jié)

Swift 中構(gòu)造器需要遵循的規(guī)則還是很多的堂淡,總結(jié)一下,有以下規(guī)則:

  • 調(diào)用相關(guān)
    1. 指定構(gòu)造器必須調(diào)用它直接父類的指定構(gòu)造器方法扒腕。
    2. 便利構(gòu)造器必須調(diào)用同一個(gè)類中定義的其它初始化方法绢淀。
    3. 便利構(gòu)造器在最后必須調(diào)用一個(gè)指定構(gòu)造器。
  • 屬性相關(guān)
    1. 指定構(gòu)造器必須要確保所有被類中提到的屬性在代理向上調(diào)用父類的指定構(gòu)造器前被初始化瘾腰,之后才能將其它構(gòu)造任務(wù)代理給父類中的構(gòu)造器更啄。
    2. 指定構(gòu)造器必須先向上代理調(diào)用父類中的構(gòu)造器,然后才能為任意屬性賦值居灯。
    3. 便利構(gòu)造器必須先代理調(diào)用同一個(gè)類中的其他構(gòu)造器祭务,然后再為屬性賦值。
    4. 構(gòu)造器在第一階段構(gòu)造完成之前怪嫌,不能調(diào)用任何實(shí)例方法义锥,不能讀取任何實(shí)例屬性的值,self 不能被引用岩灭。
  • 繼承相關(guān)
    1. 如果子類沒(méi)有定義任何的指定構(gòu)造器拌倍,那么會(huì)默認(rèn)繼承所有來(lái)自父類的指定構(gòu)造器。
    2. 如果子類提供了所有父類指定構(gòu)造器的實(shí)現(xiàn)噪径,不管是通過(guò)上一條規(guī)則繼承過(guò)來(lái)的柱恤,還是通過(guò)自定義實(shí)現(xiàn)的,它將自動(dòng)繼承所有父類的便利構(gòu)造器找爱。

說(shuō)了這么多梗顺,上個(gè)例子給大家感受下,比如我們自己寫(xiě)了一個(gè)基類MyViewController繼承自UIViewController车摄,然后在使用時(shí)寺谤,又寫(xiě)了一個(gè)類FirstViewController繼承自剛才寫(xiě)的MyViewController仑鸥,在MyViewController中有一個(gè)函數(shù),后面的子類在實(shí)例化時(shí)都會(huì)調(diào)用這個(gè)基類的函數(shù)变屁,并且這個(gè)函數(shù)由MyViewController的一個(gè)指定帶參的構(gòu)造器調(diào)用眼俊,最后我們希望在創(chuàng)建FirstViewController的實(shí)例時(shí)使用FirstViewController()這樣的方式,寫(xiě)的代碼就像這樣:

//首先粟关,基類代碼
import UIKit

   class MyViewController: UIViewController {
         //聲明一個(gè)屬性疮胖,默認(rèn)是公開(kāi)的
         var color: UIColor
         //寫(xiě)一個(gè)指定初始化器,需要調(diào)用父類指定構(gòu)造器
         init(color: UIColor) {
                 //需要在調(diào)用父類的指定構(gòu)造器前完成本類所有屬性的初始化工作
                 self.color = color
                 //調(diào)用父類的其中一個(gè)指定初始化器
                 super.init(nibName: nil, bundle: nil)
                 self.initUI()
         }
         //要寫(xiě)本類的指定初始化器就要實(shí)現(xiàn)父類要求的指定構(gòu)造器
         required init?(coder aDecoder: NSCoder) {
                 fatalError("init(coder:) has not been implemented")
         }

         func initUI() {
                 let view = UIView.init(frame: CGRect.init(x: 100, y: 100, width: 100, height: 100))
                 self.view.addSubview(view)
                 view.backgroundColor = self.color
         }
}
//基類的子類代碼
import UIKit

    class FirstViewController: MyViewController {
         override func viewDidLoad() {
             super.viewDidLoad()
         }    
         //覆載父類的指定構(gòu)造器
         override init(color: UIColor) {
             super.init(color: color)
         }    
         //新寫(xiě)一個(gè)便利構(gòu)造器闷板,需要調(diào)用本類的指定構(gòu)造器
         convenience init() {
             self.init(color: .cyan)
         }  

         required init?(coder aDecoder: NSCoder) {
             fatalError("init(coder:) has not been implemented")
         }
}

這樣即完成了這兩個(gè)類的初始化設(shè)置澎灸,比如這時(shí)候我們?cè)谄渌目刂破髦姓{(diào)用FirstViewController時(shí),只需要寫(xiě)FirstViewController()即會(huì)調(diào)用MyViewController中的initUI()函數(shù)了蛔垢。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末击孩,一起剝皮案震驚了整個(gè)濱河市迫悠,隨后出現(xiàn)的幾起案子鹏漆,更是在濱河造成了極大的恐慌,老刑警劉巖创泄,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件艺玲,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡鞠抑,警方通過(guò)查閱死者的電腦和手機(jī)饭聚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)搁拙,“玉大人秒梳,你說(shuō)我怎么就攤上這事』伲” “怎么了酪碘?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)盐茎。 經(jīng)常有香客問(wèn)我兴垦,道長(zhǎng),這世上最難降的妖魔是什么字柠? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任探越,我火速辦了婚禮,結(jié)果婚禮上窑业,老公的妹妹穿的比我還像新娘钦幔。我一直安慰自己,他們只是感情好常柄,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布节槐。 她就那樣靜靜地躺著搀庶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪铜异。 梳的紋絲不亂的頭發(fā)上哥倔,一...
    開(kāi)封第一講書(shū)人閱讀 52,156評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音揍庄,去河邊找鬼咆蒿。 笑死,一個(gè)胖子當(dāng)著我的面吹牛蚂子,可吹牛的內(nèi)容都是我干的沃测。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼食茎,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蒂破!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起别渔,我...
    開(kāi)封第一講書(shū)人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤附迷,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后哎媚,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體喇伯,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年拨与,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了稻据。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡买喧,死狀恐怖捻悯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情淤毛,我是刑警寧澤今缚,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站钱床,受9級(jí)特大地震影響荚斯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜查牌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一事期、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧纸颜,春花似錦兽泣、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)称鳞。三九已至,卻和暖如春稠鼻,著一層夾襖步出監(jiān)牢的瞬間冈止,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工候齿, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留熙暴,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓慌盯,卻偏偏與公主長(zhǎng)得像周霉,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子亚皂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

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

  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 3,817評(píng)論 1 10
  • 123.繼承 一個(gè)類可以從另外一個(gè)類繼承方法,屬性和其他特征俱箱。當(dāng)一個(gè)類繼承另外一個(gè)類時(shí), 繼承類叫子類, 被繼承的...
    無(wú)灃閱讀 1,396評(píng)論 2 4
  • 常量與變量使用let來(lái)聲明常量,使用var來(lái)聲明變量灭必。聲明的同時(shí)賦值的話狞谱,編譯器會(huì)自動(dòng)推斷類型。值永遠(yuǎn)不會(huì)被隱式轉(zhuǎn)...
    莫_名閱讀 451評(píng)論 0 1
  • 01 女人和男人本就來(lái)自不同的星球厂财,因而芋簿,注定了他們之間會(huì)有多種差異峡懈。 就連出軌都是有質(zhì)的不同的璃饱。 男人出軌多是經(jīng)...
    林姑娘與波斯貓閱讀 1,910評(píng)論 0 5
  • 身在帝都心難平,夜半常被憂傷擾肪康; 家徒四壁沒(méi)爹拼荚恶,跬步未積歲月磨; 漠然獨(dú)坐西窗下磷支,夕陽(yáng)錦繡無(wú)限好谒撼; 獨(dú)皺柳眉為何...
    小陌海蒂閱讀 202評(píng)論 2 1