Swift4.0基礎(chǔ)知識(shí)回顧

簡(jiǎn)單介紹一下Swift

Swift 語(yǔ)言由蘋(píng)果公司在 2014 年推出,用來(lái)撰寫(xiě) OS X 和 iOS 應(yīng)用程序,Swift語(yǔ)言讓?xiě)?yīng)用開(kāi)發(fā)更簡(jiǎn)單、更快、更穩(wěn)定,確保最終應(yīng)用有著更好的質(zhì)量更多了解Swift可以去 《The Swift Programming Language》中文版,這次分享給大家是Swift基礎(chǔ)知識(shí),如果你耐心看完本篇文章,并且可以理解Swift的編程技巧和方法,恭喜你可以順利的使用Swift開(kāi)發(fā)了,已經(jīng)掌握了Swift的基本語(yǔ)法,想要真正從事蘋(píng)果開(kāi)發(fā),還需要在以后的學(xué)習(xí)中不斷探索和挖掘Swift
在接下來(lái)的文章中,直接深入主題,不做過(guò)多沒(méi)必要的文字說(shuō)明,提高大家閱讀和吸收能力

一、常量和變量
常量:使用let來(lái)定義常量,定義之后不可以修改
變量:使用var來(lái)定義變量,定義之后可以修改
在使用過(guò)程中建議先定義常量,如果需要修改再修改為變量

import UIKit
let a : Int = 10
var b : Int = 20
b = 30 變量可以修改
// a = 20是錯(cuò)誤的,常量是不能修改的

二、數(shù)據(jù)類(lèi)型
1、類(lèi)型介紹
Swift中的數(shù)據(jù)類(lèi)型也有:整型/浮點(diǎn)型/對(duì)象類(lèi)型/結(jié)構(gòu)體類(lèi)型等,整型分為有符號(hào)整型和無(wú)符號(hào)整型,例如Int、UInt,浮點(diǎn)型分為Float和Double

// 定義一個(gè)Int類(lèi)型
var m : Int = 10
// 定義一個(gè)Double類(lèi)型
let n : Double = 3.14

2、類(lèi)型推導(dǎo)
Swift是強(qiáng)類(lèi)型的語(yǔ)言,Swift中任何一個(gè)標(biāo)識(shí)符都有明確的類(lèi)型,如果定義一個(gè)標(biāo)識(shí)符時(shí)有直接進(jìn)行賦值,那么標(biāo)識(shí)符后面的類(lèi)型可以省略,Swift會(huì)自動(dòng)根據(jù)后面的賦值來(lái)決定前面的標(biāo)識(shí)符的數(shù)據(jù)類(lèi)型,同時(shí)可以通過(guò)option+鼠標(biāo)左鍵來(lái)查看變量的數(shù)據(jù)類(lèi)型

Swift會(huì)自動(dòng)識(shí)別a是整數(shù),如果之后再賦值給a一個(gè)其他類(lèi)型(比如浮點(diǎn)型)數(shù)值,則會(huì)報(bào)錯(cuò)
var a = 20
// 正確寫(xiě)法
var b = 3.33
b = 6.66

3、基本運(yùn)算
Swift中在進(jìn)行基本運(yùn)算時(shí)必須保證類(lèi)型一致,否則會(huì)出錯(cuò),相同類(lèi)型之間才可以進(jìn)行運(yùn)算,Swift中沒(méi)有隱式轉(zhuǎn)換
Swift中數(shù)據(jù)類(lèi)型的轉(zhuǎn)化,Int類(lèi)型轉(zhuǎn)成Double類(lèi)型是Double(標(biāo)識(shí)符),Double類(lèi)型轉(zhuǎn)成Int類(lèi)型是Int(標(biāo)識(shí)符)

let a = 12
let b = 3.14

// 錯(cuò)誤寫(xiě)法,形同類(lèi)型之間才可以進(jìn)行運(yùn)算
// let c = a + b
// let c = a * b

// 正確寫(xiě)法,轉(zhuǎn)換類(lèi)型進(jìn)行運(yùn)算
let c = Double(a) + b
let d = a + Int(b)

三、邏輯分支
1、分支的了解
分支即if、switch、三目運(yùn)算符等判斷語(yǔ)句,通過(guò)分支語(yǔ)句可以控制程序的執(zhí)行流程
2、if分支語(yǔ)句
和OC不同,Swift判斷句可以不加(),在Swift的判斷句中必須有明確的真假,不再有非0即真,必須有明確的Bool值,Bool有兩個(gè)取值:false、true,沒(méi)有Yes、NO的使用

例1
確定值存在的判斷
let a = 12

// 錯(cuò)誤寫(xiě)法,在Swift的判斷句中必須有明確的真假,不再有非0即真
//if a {
//    print("a")
//}

// 正確寫(xiě)法
if a > 9 {
    print(a)
}
例2
可選類(lèi)型的判斷,判斷如果view有值,則設(shè)置背景
let view : UIView? = UIView()
// 錯(cuò)誤寫(xiě)法
//if view {
//    view.backgroundColor = UIColor.red
//}

if view != nil {
    view!.backgroundColor = UIColor.red
}

3、三目運(yùn)算符
Swift 中的 三目 運(yùn)算符和 OC 的用法是一樣的

var a = 12
var b = 24

var result = a > b ? a : b
println(result)

4、guard的使用
guard是很重要的,在以后的開(kāi)發(fā)中會(huì)經(jīng)常用到,來(lái)判斷該值是否是可選類(lèi)型,guard在Swift2.0就出現(xiàn)了,與if語(yǔ)句非常類(lèi)似,它設(shè)計(jì)的目的是提高程序的可讀性
guard語(yǔ)句必須帶有else語(yǔ)句,當(dāng)條件表達(dá)式為true時(shí)候跳過(guò)else語(yǔ)句中的內(nèi)容,執(zhí)行語(yǔ)句組內(nèi)容,條件表達(dá)式為false時(shí)候執(zhí)行else語(yǔ)句中的內(nèi)容,跳轉(zhuǎn)語(yǔ)句一般是return、break、continue和throw

例1
guard用法說(shuō)明
guard 條件表達(dá)式 else {
    // 條換語(yǔ)句,走這里的都是錯(cuò)誤的,判斷不符合要求的
    break
}
語(yǔ)句組,正確的執(zhí)行這里
例2
簡(jiǎn)單使用guard的用法
 func gotToSchool(time:Int) -> Void {
        guard time > 6 else {
            print("去上學(xué)")
            return
        }
        print("不去上學(xué)")
    }
gotToSchool(time: 5)

5、switch分支
Switch作為選擇結(jié)構(gòu)中必不可少的語(yǔ)句也被加入到了Swift中,只要有過(guò)編程經(jīng)驗(yàn)的人對(duì)Switch語(yǔ)句都不會(huì)感到陌生,蘋(píng)果對(duì)Switch進(jìn)行了大大的增強(qiáng),使其擁有其他語(yǔ)言中沒(méi)有的特性
基本用法和OC用法一致,switch后可以不跟(),case后可以不跟break(默認(rèn)會(huì)有break)

例1
switch對(duì)整數(shù)的判斷

let sex = 0
switch sex {
case 0 :
    print("男")
case 1 :
    print("女")
default :
    print("其他")
}
例2
一個(gè)case判斷中,可以判斷多個(gè)值,多個(gè)值以,隔開(kāi)

let sex = 0
switch sex {
case 0, 1:
    print("正常人")
default:
    print("其他")
}
例3
希望出現(xiàn)之前的case穿透,則可以使用關(guān)鍵字fallthrough

let sex = 0
switch sex {
case 0:
    fallthrough
case 1:
    print("正常人")
default:
    print("其他")
}

Switch支持多種數(shù)據(jù)類(lèi)型

① 浮點(diǎn)型的switch判斷

let f = 3.14
switch f {
case 3.14:
    print("π")
default:
    print("not π")
}
② 支持字符串類(lèi)型

let m = 5
let n = 10
var result = 0

let opration = "+"

switch opration {
    case "+":
        result = m + n
    case "-":
        result = m - n
    case "*":
        result = m * n
    case "/":
        result = m / n
default:
    result = 0
}
③ switch支持區(qū)間判斷
開(kāi)區(qū)間:0..<10 表示:0~9,不包括10
閉區(qū)間:0...10 表示:0~10

let score = 88
switch score {
case 0..<60:
    print("不及格")
case 60..<80:
    print("幾個(gè)")
case 80..<90:
    print("良好")
case 90..<100:
    print("優(yōu)秀")
default:
    print("滿分")
}

四、循環(huán)
在開(kāi)發(fā)中經(jīng)常會(huì)需要循環(huán),常見(jiàn)的循環(huán)有:for、while、do while
1、for循環(huán)

① 傳統(tǒng)寫(xiě)法
for var i = 0; i < 10; i++ {
    print(i)
}
② 區(qū)間for循環(huán)
for i in 0..<10 {
    print(i)
}

for i in 0...10 {
    print(i)
}
③ 特殊寫(xiě)法
如果在for循環(huán)中不需要用到下標(biāo)i,用`_`標(biāo)示
for _ in 0..<10 {
    print("hello")
}

2、while和do while循環(huán)

① while的判斷句必須有正確的真假,沒(méi)有非0即真,while后面的()可以省略
var a = 0
while a < 10 {
    a++
}
② do while循環(huán),使用repeat關(guān)鍵字來(lái)代替了do
let b = 0
repeat {
    print(b)
    b++
} while b < 20

五、字符串
OC和Swift中字符串的區(qū)別,在OC中字符串類(lèi)型時(shí)NSString,在Swift中字符串類(lèi)型是String,OC中字符串@"",Swift中字符串""
Swift中的String 是一個(gè)結(jié)構(gòu)體,性能更高,NSString 是一個(gè) OC 對(duì)象,性能略差,String 支持直接遍歷,Swift 提供了 String 和 NSString 之間的無(wú)縫轉(zhuǎn)換,可以使用as或者as?進(jìn)行轉(zhuǎn)換
1、遍歷字符串

// 字符串遍歷
var str = "Hello, Swift"
for c in str.characters {
    print(c)
}

2、字符串拼接

例1
let str1 = "Hello"
let str2 = "World"
let str3 = str1 + str2
例2
let name = "why"
let age = 18
let info = "my name is \(name), age is \(age)"
例3
字符串的格式化
let min = 3
let second = 4
let time = String(format: "%02d:%02d", arguments: [min, second])

3、字符串的截取
Swift中提供了特殊的截取方式,該方式非常麻煩,簡(jiǎn)單的方式是將String轉(zhuǎn)成NSString來(lái)使用,在標(biāo)識(shí)符后加:as NSString即可

let myStr = "www.baidu.com"
var subStr = (myStr as NSString).substringFromIndex(4)
subStr = (myStr as NSString).substringToIndex(3)
subStr = (myStr as NSString).substringWithRange(NSRange(location: 4, length: 5))

六、數(shù)組
數(shù)組(Array)是一串有序的由相同類(lèi)型元素構(gòu)成的集合,數(shù)組中的集合元素是有序的,可以重復(fù)出現(xiàn),swift數(shù)組類(lèi)型是Array,是一個(gè)泛型集合
1、數(shù)組的初始化
數(shù)組分成可變數(shù)組和不可變數(shù)組,使用let修飾的數(shù)組是不可變數(shù)組,使用var修飾的數(shù)組是可變數(shù)組

// 定義一個(gè)可變數(shù)組,必須初始化才能使用
var array1 : [String] = [String]()

// 定義一個(gè)不可變數(shù)組
let array2 : [NSObject] = ["xiaoming", 18]
在聲明一個(gè)Array類(lèi)型的時(shí)候可以使用下列的語(yǔ)句之一
var stuArray1:Array<String>
var stuArray2: [String]
聲明的數(shù)組需要進(jìn)行初始化才能使用,數(shù)組類(lèi)型往往是在聲明的同時(shí)進(jìn)行初始化的
// 定義時(shí)直接初始化
var array = ["xm", "xl", "my"]

// 先定義,后初始化
var array : Array<String>
array = ["xm", "xl", "my"]

2、對(duì)數(shù)組的基本操作

// 添加數(shù)據(jù)
array.append("xiaoming")

// 刪除元素
array.removeFirst()

// 修改元素
array[0] = "xiaoming"

// 取值
array[1]

3、數(shù)組的遍歷

// 遍歷數(shù)組
for i in 0..<array.count {
    print(array[i])
}

// forin方式,經(jīng)常使用
for item in array {
    print(item)
}

// 設(shè)置遍歷的區(qū)間
for item in array[0..<2] {
    print(item)
}

4、數(shù)組的合并

// 數(shù)組合并
// 注意:只有相同類(lèi)型的數(shù)組才能合并
var array = ["xm", "xl","my"]
var array1 = ["haha", "wsz"]
var array2 = array + array1;

// 不建議一個(gè)數(shù)組中存放多種類(lèi)型的數(shù)據(jù)
var array3 = [2, 3, "why"]
var array4 = ["yz", 23]
array3 + array4

七、字典
字典是由兩部分集合構(gòu)成的,一個(gè)是鍵(key)集合,一個(gè)是值(value)集合,鍵集合是不能有重復(fù)元素的,而值集合是可以重復(fù)的,鍵和值是成對(duì)出現(xiàn)的,Swift字典類(lèi)型是Dictionary,也是一個(gè)泛型集合
1、Swift中的可變和不可變字典,使用let修飾的數(shù)組是不可變字典,使用var修飾的數(shù)組是可變字典

// 定義一個(gè)可變字典
var dict1 : [String : NSObject] = [String : NSObject]()

// 定義一個(gè)不可變字典
let dict2 = ["name" : "xl", "age" : 18]
在聲明一個(gè)Dictionary類(lèi)型的時(shí)候可以使用下面的語(yǔ)句之一
var dict1: Dictionary<Int, String>
var dict2: [Int: String]
聲明的字典需要進(jìn)行初始化才能使用,字典類(lèi)型往往是在聲明的同時(shí)進(jìn)行初始化的
// 定義字典的同時(shí),進(jìn)行初始化
var dict = ["name" : "why", "age" : 18]

// swift中任意對(duì)象,通常不使用NSObject,使用AnyObject
var dict : Dictionary<String, AnyObject>
dict = ["name" : "why", "age" : 18]

2、字典的基本操作

// 添加數(shù)據(jù)
dict["height"] = 1.80
dict["weight"] = 65.0

// 刪除字段
dict.removeValueForKey("height")

// 修改字典
dict["name"] = "lmj"

// 查詢字典
dict["name"]

3、字典的遍歷

// 遍歷字典中所有的值
for value in dict.values {
    print(value)
}
// 遍歷字典中所有的鍵
for key in dict.keys {
    print(key)
}
// 遍歷所有的鍵值對(duì)
for (key, value) in dict {
    print(key)
    print(value)
}

4、字典的合并

// 字典的合并
var dict1 = ["name" : "xl", "age" : 20]
var dict2 = ["height" : 1.87, "phoneNum" : "+86 110"]
// 字典不可以相加合并
for (key, value) in dict1 {
    dict2[key] = value
}

八、元組
元組是Swift中特有的,OC中并沒(méi)有相關(guān)類(lèi)型,類(lèi)似于數(shù)組或者字典,可以用于定義一組數(shù)據(jù),組成元組類(lèi)型的數(shù)據(jù)可以稱為“元素”
1、元組的定義

元組的常見(jiàn)寫(xiě)法
// 使用元組描述一個(gè)人的信息
("1001", "張三", 30, 90)
// 給元素加上元素名稱,之后可以通過(guò)元素名稱訪問(wèn)元素
(id:"1001", name:"張三", english_score:30, chinese_score:90)

2、元祖的簡(jiǎn)單使用

// 元祖使用

// 寫(xiě)法一:
let object = (xiaoming, "18")
print(object.0)
print(object.1)

// 寫(xiě)法二:
let object = (name : xiaoming, age : "18")
print(object.name)
print(object.age)

// 寫(xiě)法三:
let (name, age) = (xiaoming, "18")
print(name)
print(age)

九、可選類(lèi)型
在OC開(kāi)發(fā)中,如果一個(gè)變量暫停不使用,可以賦值為0(基本屬性類(lèi)型)或者賦值為空(對(duì)象類(lèi)型),在swift開(kāi)發(fā)中,nil也是一個(gè)特殊的類(lèi)型.因?yàn)楹驼鎸?shí)的類(lèi)型不匹配是不能賦值的(swift是強(qiáng)類(lèi)型語(yǔ)言),但是開(kāi)發(fā)中賦值nil,在所難免,因此推出了可選類(lèi)型
可選類(lèi)型的取值:空值或者有值
1、定義可選類(lèi)型

// 寫(xiě)法一:定義可選類(lèi)型
let name : Optional<String> = nil

// 寫(xiě)法二:定義可選類(lèi)型,語(yǔ)法糖(常用)
let name : String? = nil

2、可選類(lèi)型的使用

// 定義可選類(lèi)型
var string : Optional<String> = nil

// 給可選類(lèi)型賦值
string = "Hello world"

// 打印結(jié)果
print(string)
// 結(jié)果:Optional("Hello world")\n

// 取出可選類(lèi)型的真實(shí)值(解包)
print(string!)
// 結(jié)果:Hello world\n

// 注意:如果可選類(lèi)型為nil,強(qiáng)制取出其中的值(解包),會(huì)出錯(cuò)
string = nil
print(string!) // 報(bào)錯(cuò)

// 正確寫(xiě)法:
if string != nil {
    print(string!)
}

// 簡(jiǎn)單寫(xiě)法:為了讓在if語(yǔ)句中可以方便使用string
// 可選綁定
if let str = string {
    print(str)
}

十、函數(shù)
1、函數(shù)介紹
函數(shù)相當(dāng)于OC中的方法,函數(shù)的格式如下

func 函數(shù)名(參數(shù)列表) -> 返回值類(lèi)型 {
    代碼塊
    return 返回值
}

func是關(guān)鍵字,多個(gè)參數(shù)列表之間可以用逗號(hào)(,)分隔,也可以沒(méi)有參數(shù),使用箭頭“->”指向返回值類(lèi)型,如果函數(shù)沒(méi)有返回值,返回值為Void.并且“-> 返回值類(lèi)型”部分可以省略

2、常見(jiàn)的函數(shù)類(lèi)型

① 沒(méi)有參數(shù),沒(méi)用返回值
func about() -> Void {
    print("iphone6s plus")
}
// 調(diào)用函數(shù)
about()

如果沒(méi)用返回值,Void可以寫(xiě)成()
func about1() -> () {
    print("iphone6s plus")
}
// 如果沒(méi)有返回值,后面的內(nèi)容可以都不寫(xiě)
func about2() {
    print("iphone6s plus")
}
about2()

② 有參數(shù),沒(méi)用返回值
func callPhone(phoneNum : String) {
    print("打電話給\(phoneNum)")
}
callPhone("+86 110")

③ 沒(méi)用參數(shù),有返回值
func readMessage() -> String {
    return "吃飯了嗎?"
}
var str = readMessage()
print(str)

④ 有參數(shù),有返回值
func sum(num1 : Int,num2 : Int) -> Int {
    return num1 + num2
}
var result = sum(20,num2: 30)
print(result)

3、函數(shù)的使用
① 外部參數(shù)和內(nèi)部參數(shù)
在函數(shù)內(nèi)部可以看到的參數(shù),就是內(nèi)部參數(shù),在函數(shù)外面可以看到的參數(shù),就是外部參數(shù),默認(rèn)情況下,從第二個(gè)參數(shù)開(kāi)始,參數(shù)名稱既是內(nèi)部參數(shù)也是外部參數(shù),如果第一個(gè)參數(shù)也想要有外部參數(shù),可以設(shè)置標(biāo)簽,在變量名前加標(biāo)簽即可,如果不想要外部參數(shù),可以在參數(shù)名稱前加_

// num1和a是外部參數(shù)的名稱
func ride(num1 num1 : Int, a num2 : Int, b num3 : Int) -> Int {
    return num1 * num2 * num3
}
var result1 = ride(num1: 20, a: 4, b: 5)

// 方法的重載:方法名稱相同,但是參數(shù)不同,可以稱之為方法的重載(了解)
func ride(num1: Int, _ num2 :Int) -> Int {
    return num1 * num2
}

var result2 = ride(20, 20)

② 默認(rèn)參數(shù)
如果沒(méi)有傳入具體的參數(shù),可以使用默認(rèn)參數(shù)

func makecoffee(type :String = "卡布奇諾") -> String {
    return "制作一杯\(type)咖啡。"
}

let coffee1 = makecoffee("鐵觀音")
let coffee2 = makecoffee()

③ 可變參數(shù)
Swift中函數(shù)的參數(shù)個(gè)數(shù)可以變化,它可以接受不確定數(shù)量的輸入類(lèi)型參數(shù),它們必須具有相同的類(lèi)型,我們可以通過(guò)在參數(shù)類(lèi)型名后面加入(...)的方式來(lái)指示這是可變參數(shù)

func sum(numbers:Double...) -> Double {
    var total: Double = 0
    for number in numbers {
        total += number
    }
    return total
}

sum(100.0, 20, 30)
sum(30, 80)

④ 引用類(lèi)型(指針的傳遞)
默認(rèn)情況下,函數(shù)的參數(shù)是值傳遞,如果想改變外面的變量,則需要傳遞變量的地址,必須是變量,因?yàn)樾枰趦?nèi)部改變其值,Swift提供的inout關(guān)鍵字就可以實(shí)現(xiàn)

// 函數(shù)一:值傳遞
func swap(var a : Int, var b : Int) {
    let temp = a;
    a = b;
    b = temp
    print("a:\(a), b:\(b)")
}

var a = 10
var b = 20
swap(a, b: b)
print("a:\(a), b:\(b)")

// 函數(shù)二:指針的傳遞
func swap1(inout a : Int, inout b : Int) {
    let temp = a
    a = b
    b = temp

    print("a:\(a), b:\(b)")
}

swap1(&a, b: &b)
print("a:\(a), b:\(b)")

⑤ 函數(shù)的嵌套使用
swift中函數(shù)可以嵌套使用,即函數(shù)中包含函數(shù),但是不推薦該寫(xiě)法
十一、類(lèi)的使用
1、類(lèi)的介紹和定義
Swift也是一門(mén)面向?qū)ο箝_(kāi)發(fā)的語(yǔ)言,面向?qū)ο蟮幕A(chǔ)是類(lèi),類(lèi)產(chǎn)生了對(duì)象,class是Swift中的關(guān)鍵字,用于定義類(lèi)

定義的類(lèi),可以沒(méi)有父類(lèi).那么該類(lèi)是rootClass,通常情況下,定義類(lèi)時(shí),繼承自NSObject(非OC的NSObject)
class 類(lèi)名 : SuperClass {
    // 定義屬性和方法
}

2、定義類(lèi)的屬性
Swift中類(lèi)的屬性有多種:存儲(chǔ)屬性,存儲(chǔ)實(shí)例的常量和變量;計(jì)算屬性,通過(guò)某種方式計(jì)算出來(lái)的屬性;類(lèi)屬性,與整個(gè)類(lèi)自身相關(guān)的屬性
① 存儲(chǔ)屬性
存儲(chǔ)屬性是最簡(jiǎn)單的屬性,它作為類(lèi)實(shí)例的一部分,用于存儲(chǔ)常量和變量,可以給存儲(chǔ)屬性提供一個(gè)默認(rèn)值,也可以在初始化方法中對(duì)其進(jìn)行初始化

// 給存儲(chǔ)屬性賦值
stu.age = 10
stu.name = "xiaoming"

stu.chineseScore = 89.0
stu.mathScore = 98.0

② 計(jì)算屬性
計(jì)算屬性并不存儲(chǔ)實(shí)際的值,而是提供一個(gè)getter和一個(gè)可選的setter來(lái)間接獲取和設(shè)置其它屬性,計(jì)算屬性一般只提供getter方法,如果只提供getter,而不提供setter,則該計(jì)算屬性為只讀屬性,并且可以省略get{}

class Student : NSObject {
    // 存儲(chǔ)屬性
    var age : Int = 0
    var name : String?

    var chineseScore : Double = 0.0
    var mathScore : Double = 0.0

    // 計(jì)算屬性
    var averageScore : Double {
        get {
            return (chineseScore + mathScore) / 2
        }

        // 沒(méi)有意義,因?yàn)橹螳@取值時(shí)依然是計(jì)算得到的
        // newValue是系統(tǒng)分配的變量名,內(nèi)部存儲(chǔ)著新值
        set {
            self.averageScore = newValue
        }
    }
}

③ 類(lèi)屬性
類(lèi)屬性是與類(lèi)相關(guān)聯(lián)的,而不是與類(lèi)的實(shí)例相關(guān)聯(lián),類(lèi)屬性的設(shè)置和修改,需要通過(guò)類(lèi)來(lái)完成,類(lèi)屬性使用static來(lái)修飾

class Student : NSObject {
    // 類(lèi)屬性
    static var corseCount : Int = 0
}

// 設(shè)置類(lèi)屬性的值
Student.corseCount = 3
// 取出類(lèi)屬性的值
print(Student.corseCount)

④ 監(jiān)聽(tīng)屬性的改變
在OC中我們可以重寫(xiě)set方法來(lái)監(jiān)聽(tīng)屬性的改變,在Swift中可以通過(guò)屬性觀察者來(lái)監(jiān)聽(tīng)和響應(yīng)屬性值的變化,通常是監(jiān)聽(tīng)存儲(chǔ)屬性和類(lèi)屬性的改變,(對(duì)于計(jì)算屬性,我們不需要定義屬性觀察者,因?yàn)槲覀兛梢栽谟?jì)算屬性的setter中直接觀察并響應(yīng)這種值的變化)
willSet:在屬性值被存儲(chǔ)之前設(shè)置,此時(shí)新屬性值作為一個(gè)常量參數(shù)被傳入,該參數(shù)名默認(rèn)為newValue,我們可以自己定義該參數(shù)名;didSet:在新屬性值被存儲(chǔ)后立即調(diào)用,與willSet相同,此時(shí)傳入的是屬性的舊值,默認(rèn)參數(shù)名為oldValue;
willSet與didSet只有在屬性第一次被設(shè)置時(shí)才會(huì)調(diào)用,在初始化時(shí),不會(huì)去調(diào)用這些監(jiān)聽(tīng)方法

class Person : NSObject {
    var name : String? {
        // 可以給newValue自定義名稱
        willSet (new){ // 屬性即將改變,還未改變時(shí)會(huì)調(diào)用的方法
            // 在該方法中有一個(gè)默認(rèn)的系統(tǒng)屬性newValue,用于存儲(chǔ)新值
            print(name)
            print(new)
        }
        // 可以給oldValue自定義名稱
        didSet (old) { // 屬性值已經(jīng)改變了,會(huì)調(diào)用的方法
            // 在該方法中有一個(gè)默認(rèn)的系統(tǒng)屬性oldValue,用于存儲(chǔ)舊值
            print(name)
            print(old)
        }
    }
    var age : Int = 0
    var height : Double = 0.0
}

let p : Person = Person()

// 在賦值時(shí),監(jiān)聽(tīng)該屬性的改變
// 在OC中是通過(guò)重寫(xiě)set方法
// 在swift中,可以給屬性添加監(jiān)聽(tīng)器
p.name = "xiaoming"

十二、類(lèi)的構(gòu)造函數(shù)
構(gòu)造函數(shù)類(lèi)似于OC中的初始化方法init方法,默認(rèn)情況下載創(chuàng)建一個(gè)類(lèi)時(shí),必然會(huì)調(diào)用一個(gè)構(gòu)造函數(shù),即便是沒(méi)有編寫(xiě)任何構(gòu)造函數(shù),編譯器也會(huì)提供一個(gè)默認(rèn)的構(gòu)造函數(shù),如果是繼承自NSObject,可以對(duì)父類(lèi)的構(gòu)造函數(shù)進(jìn)行重寫(xiě)
1、構(gòu)造函數(shù)的基本使用
① 類(lèi)的屬性必須有值,如果不是在定義時(shí)初始化值,可以在構(gòu)造函數(shù)中賦值

class Person: NSObject {
    var name : String
    var age : Int
    // 重寫(xiě)了NSObject(父類(lèi))的構(gòu)造方法
    override init() {
        name = ""
        age = 0
    }
}

// 創(chuàng)建一個(gè)Person對(duì)象
let p = Person()

② 初始化時(shí)給屬性賦值
我們?cè)趧?chuàng)建一個(gè)對(duì)象時(shí)就會(huì)給屬性賦值,可以自定義構(gòu)造函數(shù),如果自定義了構(gòu)造函數(shù),會(huì)覆蓋init()方法,即不在有默認(rèn)的構(gòu)造函數(shù)

class Person: NSObject {
    var name : String
    var age : Int

    // 自定義構(gòu)造函數(shù),會(huì)覆蓋init()函數(shù)
    init(name : String, age : Int) {
        self.name = name
        self.age = age
    }
}

// 創(chuàng)建一個(gè)Person對(duì)象
let p = Person(name: "xiaoming", age: 18)

③ 字典轉(zhuǎn)模型(初始化時(shí)傳入字典)

例1
class Person: NSObject {
    var name : String
    var age : Int

    // 自定義構(gòu)造函數(shù),會(huì)覆蓋init()函數(shù)
    init(dict : [String : NSObject]) {
        name = dict["name"] as! String
        age = dict["age"] as! Int
    }
}

// 創(chuàng)建一個(gè)Person對(duì)象
let dict = ["name" : "xiaoming", "age" : 18]
let p = Person(dict: dict)
例2
利用KVC字典轉(zhuǎn)模型
class Person: NSObject {
    // 結(jié)構(gòu)體或者類(lèi)的類(lèi)型,必須是可選類(lèi)型,因?yàn)椴荒鼙WC一定會(huì)賦值
    var name : String?

    // 基本數(shù)據(jù)類(lèi)型不能是可選類(lèi)型,否則KVC無(wú)法轉(zhuǎn)化
    var age : Int = 0

    // 自定義構(gòu)造函數(shù),會(huì)覆蓋init()函數(shù)
    init(dict : [String : NSObject]) {
        // 必須先初始化對(duì)象
        super.init()

        // 調(diào)用對(duì)象的KVC方法字典轉(zhuǎn)模型
        setValuesForKeysWithDictionary(dict)
    }
}

// 創(chuàng)建一個(gè)Person對(duì)象
let dict = ["name" : "xiaoming", "age" : 18]
let p = Person(dict: dict)

十三、閉包
Swift閉包和OC中的block非常相似,OC中的block是匿名的函數(shù),Swift中的閉包是一個(gè)特殊的函數(shù),block和閉包都經(jīng)常用于回調(diào)
1、OC中Block的使用

首先介紹一下OC中Block寫(xiě)法
① 第一種Block方式

@property (nonatomic, copy) void(^callBack)(NSString *name);
callBack 是block對(duì)象
回調(diào)方法
if(_callBack){
_callBack(name)
}

② 第二種Block方式

typedef void(^CallBack)(NSString *str);
@property (nonatomic, copy) CallBack callback;
callback是block對(duì)象
回調(diào)方法
if(_callBack){
_callBack(name)
}

③ 第三種Block方式

- (void)setUpWith:(void(^)(NSString *str))callback;
callback是block對(duì)象
回調(diào)方法
if(_callBack){
_callBack(name)
}
總結(jié)
Block的寫(xiě)法:
    類(lèi)型:
    返回值類(lèi)型(^block的名稱)(block的參數(shù))

    值:
    ^(參數(shù)列表) {
        // 執(zhí)行的代碼
    };

2、Swift中閉包的使用
① 第一種閉包方式

var callBack : (()->())?

② 第二種閉包方式

func loadRequest(callBack : ()->()){
                callBack()
    }
總結(jié)
閉包的寫(xiě)法:
   callBack: (形參列表) -> (返回值類(lèi)型)
    類(lèi)型:(形參列表) -> (返回值類(lèi)型)
    值:
    {
        (形參) -> 返回值類(lèi)型 in
        // 執(zhí)行代碼
    }

閉包的簡(jiǎn)寫(xiě),如果閉包沒(méi)有參數(shù),沒(méi)有返回值,in和in之前的內(nèi)容可以省略

尾隨閉包寫(xiě)法
① 如果閉包是函數(shù)的最后一個(gè)參數(shù),則可以將閉包寫(xiě)在()后面
    httpTool.loadRequest() {
        print("回到主線程", NSThread.currentThread());
    }
② 如果函數(shù)只有一個(gè)參數(shù),并且這個(gè)參數(shù)是閉包,那么()可以不寫(xiě)
    // 開(kāi)發(fā)中建議該寫(xiě)法
    httpTool.loadRequest {
        print("回到主線程", NSThread.currentThread());
    }

3、閉包的循環(huán)引用
如果在HttpTool中有對(duì)閉包進(jìn)行強(qiáng)引用,則會(huì)形成循環(huán)引用,在Swift中檢測(cè)一個(gè)對(duì)象是否銷(xiāo)毀,可以實(shí)現(xiàn)對(duì)象的deinit函數(shù)

// 析構(gòu)函數(shù)(相當(dāng)于OC中dealloc方法)
    deinit {
        print("ViewController----deinit")
    }

4、swift中解決循環(huán)引用的方式
① 使用weak,對(duì)當(dāng)前控制器使用弱引用
但是因?yàn)閟elf可能有值也可能沒(méi)有值,因此weakSelf是一個(gè)可選類(lèi)型,在真正使用時(shí)可以對(duì)其強(qiáng)制解包(該處強(qiáng)制解包沒(méi)有問(wèn)題,因?yàn)榭刂破饕欢ù嬖?否則無(wú)法調(diào)用所在函數(shù))

解決一
weak var weakSelf = self
    httpTool.loadData {
        print("加載數(shù)據(jù)完成,更新界面:", NSThread.currentThread())
        weakSelf!.view.backgroundColor = UIColor.redColor()
    }

② 可以寫(xiě)在閉包中,并且在閉包中用到的self都是弱引用

解決二
 httpTool.loadData {[weak self] () -> () in
        print("加載數(shù)據(jù)完成,更新界面:", NSThread.currentThread())
        self!.view.backgroundColor = UIColor.redColor()
    }

③ 使用關(guān)鍵字unowned
unowned 更像OC中的 unsafe_unretained,unowned 表示即使它原來(lái)引用的對(duì)象被釋放了,仍然會(huì)保持對(duì)被已經(jīng)釋放了的對(duì)象的一個(gè) "無(wú)效的" 引用,它不能是 Optional 值,也不會(huì)被指向 nil

解決三
httpTool.loadData {[unowned self] () -> () in
        print("加載數(shù)據(jù)完成,更新界面:", NSThread.currentThread())
        self.view.backgroundColor = UIColor.redColor()
    }

十四、懶加載
swift中也有懶加載的方式,希望所有的對(duì)象在使用時(shí)才真正加載到內(nèi)存中,和OC不同的是swift有專門(mén)的關(guān)鍵字來(lái)實(shí)現(xiàn)懶加載,lazy關(guān)鍵字可以用于定義某一個(gè)屬性懶加載
1、懶加載普通方式

lazy var 變量:類(lèi)型 = 系統(tǒng)類(lèi)()
lazy var button:UIButton = UIButton()

2、懶加載升級(jí)方式

lazy var array : [String] = {
        () -> [String] in
        return ["xiaoming", "xl", "lisi"]
    }()

心得體會(huì):
Swift好用,如果你讀完本篇文章基本上掌握了Swift基礎(chǔ)知識(shí),剩下的就是實(shí)戰(zhàn)了,實(shí)戰(zhàn)會(huì)增加你編寫(xiě)Swift的能力,對(duì)Swift有更深的理解,后期也會(huì)補(bǔ)充新的Swift知識(shí),也會(huì)分享自己的開(kāi)源Swift項(xiàng)目共大家學(xué)習(xí)討論,請(qǐng)關(guān)注下我的github賬號(hào)lb2281075105,開(kāi)始分享自己的項(xiàng)目和Demo,如果更好的意見(jiàn)請(qǐng)及時(shí)給我說(shuō)哦,合理我會(huì)毫不猶豫采納,謝謝,您的點(diǎn)贊會(huì)更加激勵(lì)我的熱情。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 4,200評(píng)論 1 10
  • Swift 介紹 簡(jiǎn)介 Swift 語(yǔ)言由蘋(píng)果公司在 2014 年推出,用來(lái)撰寫(xiě) OS X 和 iOS 應(yīng)用程序 ...
    大L君閱讀 3,436評(píng)論 3 25
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,432評(píng)論 4 61
  • 常量與變量使用let來(lái)聲明常量,使用var來(lái)聲明變量。聲明的同時(shí)賦值的話,編譯器會(huì)自動(dòng)推斷類(lèi)型。值永遠(yuǎn)不會(huì)被隱式轉(zhuǎn)...
    莫_名閱讀 536評(píng)論 0 1
  • 微醺醉臥深秋借著那遠(yuǎn)方的閃亮星辰讓我看到了你熟睡的垂眸用鼻尖輕輕靠近你的耳朵呢喃的說(shuō)你的愛(ài)安撫了我的靈魂我的心回歸...
    意匠寶旺閱讀 397評(píng)論 0 0

友情鏈接更多精彩內(nèi)容