Swift基礎知識4

姓名:謝艾芳? 學號:16040410073

Swift基礎知識4(接上一篇)

轉自http://www.lxweimin.com/p/02ab8c6c1f9f

〖嵌牛導讀〗Swift 語言由蘋果公司在 2014 年推出,用來撰寫 OS X 和 iOS 應用程序,Swift語言讓應用開發更簡單、更快、更穩定,確保最終應用有著更好的質量

〖嵌牛鼻子〗Swift基礎知識 Swift的編程技巧和方法

〖嵌牛提問〗如何簡單學習Swift基本編程語言?

〖嵌牛正文〗

十一、類的使用

1、類的介紹和定義

Swift也是一門面向對象開發的語言,面向對象的基礎是類,類產生了對象,class是Swift中的關鍵字,用于定義類

定義的類,可以沒有父類.那么該類是rootClass,通常情況下,定義類時,繼承自NSObject(非OC的NSObject)

class 類名 : SuperClass {

? ? // 定義屬性和方法

}

2、定義類的屬性

Swift中類的屬性有多種:存儲屬性,存儲實例的常量和變量;計算屬性,通過某種方式計算出來的屬性;類屬性,與整個類自身相關的屬性

① 存儲屬性

存儲屬性是最簡單的屬性,它作為類實例的一部分,用于存儲常量和變量,可以給存儲屬性提供一個默認值,也可以在初始化方法中對其進行初始化

// 給存儲屬性賦值

stu.age = 10

stu.name = "xiaoming"

stu.chineseScore = 89.0

stu.mathScore = 98.0

② 計算屬性

計算屬性并不存儲實際的值,而是提供一個getter和一個可選的setter來間接獲取和設置其它屬性,計算屬性一般只提供getter方法,如果只提供getter,而不提供setter,則該計算屬性為只讀屬性,并且可以省略get{}

class Student : NSObject {

? ? // 存儲屬性

? ? var age : Int = 0

? ? var name : String?

? ? var chineseScore : Double = 0.0

? ? var mathScore : Double = 0.0

? ? // 計算屬性

? ? var averageScore : Double {

? ? ? ? get {

? ? ? ? ? ? return (chineseScore + mathScore) / 2

? ? ? ? }

? ? ? ? // 沒有意義,因為之后獲取值時依然是計算得到的

? ? ? ? // newValue是系統分配的變量名,內部存儲著新值

? ? ? ? set {

? ? ? ? ? ? self.averageScore = newValue

? ? ? ? }

? ? }

}

③ 類屬性

類屬性是與類相關聯的,而不是與類的實例相關聯,類屬性的設置和修改,需要通過類來完成,類屬性使用static來修飾

class Student : NSObject {

? ? // 類屬性

? ? static var corseCount : Int = 0

}

// 設置類屬性的值

Student.corseCount = 3

// 取出類屬性的值

print(Student.corseCount)

④ 監聽屬性的改變

在OC中我們可以重寫set方法來監聽屬性的改變,在Swift中可以通過屬性觀察者來監聽和響應屬性值的變化,通常是監聽存儲屬性和類屬性的改變,(對于計算屬性,我們不需要定義屬性觀察者,因為我們可以在計算屬性的setter中直接觀察并響應這種值的變化)

willSet:在屬性值被存儲之前設置,此時新屬性值作為一個常量參數被傳入,該參數名默認為newValue,我們可以自己定義該參數名;didSet:在新屬性值被存儲后立即調用,與willSet相同,此時傳入的是屬性的舊值,默認參數名為oldValue;

willSet與didSet只有在屬性第一次被設置時才會調用,在初始化時,不會去調用這些監聽方法

class Person : NSObject {

? ? var name : String? {

? ? ? ? // 可以給newValue自定義名稱

? ? ? ? willSet (new){ // 屬性即將改變,還未改變時會調用的方法

? ? ? ? ? ? // 在該方法中有一個默認的系統屬性newValue,用于存儲新值

? ? ? ? ? ? print(name)

? ? ? ? ? ? print(new)

? ? ? ? }

? ? ? ? // 可以給oldValue自定義名稱

? ? ? ? didSet (old) { // 屬性值已經改變了,會調用的方法

? ? ? ? ? ? // 在該方法中有一個默認的系統屬性oldValue,用于存儲舊值

? ? ? ? ? ? print(name)

? ? ? ? ? ? print(old)

? ? ? ? }

? ? }

? ? var age : Int = 0

? ? var height : Double = 0.0

}

let p : Person = Person()

// 在賦值時,監聽該屬性的改變

// 在OC中是通過重寫set方法

// 在swift中,可以給屬性添加監聽器

p.name = "xiaoming"

十二、類的構造函數

構造函數類似于OC中的初始化方法init方法,默認情況下載創建一個類時,必然會調用一個構造函數,即便是沒有編寫任何構造函數,編譯器也會提供一個默認的構造函數,如果是繼承自NSObject,可以對父類的構造函數進行重寫

1、構造函數的基本使用

① 類的屬性必須有值,如果不是在定義時初始化值,可以在構造函數中賦值

class Person: NSObject {

? ? var name : String

? ? var age : Int

? ? // 重寫了NSObject(父類)的構造方法

? ? override init() {

? ? ? ? name = ""

? ? ? ? age = 0

? ? }

}

// 創建一個Person對象

let p = Person()

② 初始化時給屬性賦值

我們在創建一個對象時就會給屬性賦值,可以自定義構造函數,如果自定義了構造函數,會覆蓋init()方法,即不在有默認的構造函數

class Person: NSObject {

? ? var name : String

? ? var age : Int

? ? // 自定義構造函數,會覆蓋init()函數

? ? init(name : String, age : Int) {

? ? ? ? self.name = name

? ? ? ? self.age = age

? ? }

}

// 創建一個Person對象

let p = Person(name: "xiaoming", age: 18)

③ 字典轉模型(初始化時傳入字典)

例1

class Person: NSObject {

? ? var name : String

? ? var age : Int

? ? // 自定義構造函數,會覆蓋init()函數

? ? init(dict : [String : NSObject]) {

? ? ? ? name = dict["name"] as! String

? ? ? ? age = dict["age"] as! Int

? ? }

}

// 創建一個Person對象

let dict = ["name" : "xiaoming", "age" : 18]

let p = Person(dict: dict)

例2

利用KVC字典轉模型

class Person: NSObject {

? ? // 結構體或者類的類型,必須是可選類型,因為不能保證一定會賦值

? ? var name : String?

? ? // 基本數據類型不能是可選類型,否則KVC無法轉化

? ? var age : Int = 0

? ? // 自定義構造函數,會覆蓋init()函數

? ? init(dict : [String : NSObject]) {

? ? ? ? // 必須先初始化對象

? ? ? ? super.init()

? ? ? ? // 調用對象的KVC方法字典轉模型

? ? ? ? setValuesForKeysWithDictionary(dict)

? ? }

}

// 創建一個Person對象

let dict = ["name" : "xiaoming", "age" : 18]

let p = Person(dict: dict)

十三、閉包

Swift閉包和OC中的block非常相似,OC中的block是匿名的函數,Swift中的閉包是一個特殊的函數,block和閉包都經常用于回調

1、OC中Block的使用

首先介紹一下OC中Block寫法

① 第一種Block方式

@property (nonatomic, copy) void(^callBack)(NSString *name);

callBack 是block對象

回調方法

if(_callBack){

_callBack(name)

}

② 第二種Block方式

typedef void(^CallBack)(NSString *str);

@property (nonatomic, copy) CallBack callback;

callback是block對象

回調方法

if(_callBack){

_callBack(name)

}

③ 第三種Block方式

- (void)setUpWith:(void(^)(NSString *str))callback;

callback是block對象

回調方法

if(_callBack){

_callBack(name)

}

總結

Block的寫法:

? ? 類型:

? ? 返回值類型(^block的名稱)(block的參數)

? ? 值:

? ? ^(參數列表) {

? ? ? ? // 執行的代碼

? ? };

2、Swift中閉包的使用

① 第一種閉包方式

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

② 第二種閉包方式

func loadRequest(callBack : ()->()){

? ? ? ? ? ? ? ? callBack()

? ? }

總結

閉包的寫法:

? callBack: (形參列表) -> (返回值類型)

? ? 類型:(形參列表) -> (返回值類型)

? ? 值:

? ? {

? ? ? ? (形參) -> 返回值類型 in

? ? ? ? // 執行代碼

? ? }

閉包的簡寫,如果閉包沒有參數,沒有返回值,in和in之前的內容可以省略

尾隨閉包寫法

① 如果閉包是函數的最后一個參數,則可以將閉包寫在()后面

? ? httpTool.loadRequest() {

? ? ? ? print("回到主線程", NSThread.currentThread());

? ? }

② 如果函數只有一個參數,并且這個參數是閉包,那么()可以不寫

? ? // 開發中建議該寫法

? ? httpTool.loadRequest {

? ? ? ? print("回到主線程", NSThread.currentThread());

? ? }

3、閉包的循環引用

如果在HttpTool中有對閉包進行強引用,則會形成循環引用,在Swift中檢測一個對象是否銷毀,可以實現對象的deinit函數

// 析構函數(相當于OC中dealloc方法)

? ? deinit {

? ? ? ? print("ViewController----deinit")

? ? }

4、swift中解決循環引用的方式

① 使用weak,對當前控制器使用弱引用

但是因為self可能有值也可能沒有值,因此weakSelf是一個可選類型,在真正使用時可以對其強制解包(該處強制解包沒有問題,因為控制器一定存在,否則無法調用所在函數)

解決一

weak var weakSelf = self

? ? httpTool.loadData {

? ? ? ? print("加載數據完成,更新界面:", NSThread.currentThread())

? ? ? ? weakSelf!.view.backgroundColor = UIColor.redColor()

? ? }

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

解決二

httpTool.loadData {[weak self] () -> () in

? ? ? ? print("加載數據完成,更新界面:", NSThread.currentThread())

? ? ? ? self!.view.backgroundColor = UIColor.redColor()

? ? }

③ 使用關鍵字unowned

unowned 更像OC中的 unsafe_unretained,unowned 表示即使它原來引用的對象被釋放了,仍然會保持對被已經釋放了的對象的一個 "無效的" 引用,它不能是 Optional 值,也不會被指向 nil

解決三

httpTool.loadData {[unowned self] () -> () in

? ? ? ? print("加載數據完成,更新界面:", NSThread.currentThread())

? ? ? ? self.view.backgroundColor = UIColor.redColor()

? ? }

十四、懶加載

swift中也有懶加載的方式,希望所有的對象在使用時才真正加載到內存中,和OC不同的是swift有專門的關鍵字來實現懶加載,lazy關鍵字可以用于定義某一個屬性懶加載

1、懶加載普通方式

lazy var 變量:類型 = 系統類()

lazy var button:UIButton = UIButton()

2、懶加載升級方式

lazy var array : [String] = {

? ? ? ? () -> [String] in

? ? ? ? return ["xiaoming", "xl", "lisi"]

? ? }()

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容