每日一問17——swift基礎(chǔ)(03)

枚舉類型

swift中使用enum關(guān)鍵字聲明枚舉。并且可以指定枚舉的類型

方式一、
enum Dirction : Int{
    case east = 0
    case west = 1
    case north = 2
    case south = 3
}

enum NethodType : String{
    case get = "get"
    case post = "post"
    case put = "put"
    case delete = "delete"
}

方式一枚舉類型甚至可以為String類型。

方式二、
enum type : Int{ //這種方式只支持Int
    case enum1 = 0,enum2,enum3,enum4,enum5
}

方式二對于枚舉數(shù)量較多的情況下可以快速書寫,但這種方式類型只支持Int

創(chuàng)建具體的枚舉
第一種:
let type1 : NethodType = .get
第二種:
let type2 = NethodType.post

結(jié)構(gòu)體

結(jié)構(gòu)體定義格式如下:

struct 結(jié)構(gòu)體名稱 {
    屬性或方法
}

與oc不同,swift中結(jié)構(gòu)體可以添加方法

定義結(jié)構(gòu)體
struct location {
    //屬性
    var x : Double
    var y : Double

    //方法
    func test() {
        print("結(jié)構(gòu)體中的test方法")
    }
}
結(jié)構(gòu)體的構(gòu)造函數(shù)

一般情況下,結(jié)構(gòu)體為我們提供了默認的構(gòu)造函數(shù),需要我們?yōu)榻Y(jié)構(gòu)體中每一個屬性賦值。但我們也可以自定義構(gòu)造函數(shù)。

  • 構(gòu)造函數(shù)用init開頭;
  • 構(gòu)造函數(shù)不需要返回值;
  • 構(gòu)造函數(shù)必須保證所有成員屬性被初始化
在上面結(jié)構(gòu)體中添加這個函數(shù)
假設(shè)我們需要傳入一個string為10,20,將10賦值給x,將20賦值給y
init(xyStr : String) {
        let array = xyStr.components(separatedBy: ",")
        let item1 = array[0]
        let item2 = array[1]

        //?? 先判斷前面可選類型是否有值, 有值系統(tǒng)解包,無值使用后面提供的值
        self.x = Double(item1) ?? 0
        self.y = Double(item2) ?? 0
    }
改變成員屬性

我們可以直接在函數(shù)中修改結(jié)構(gòu)體中成員屬性的值,但需要在函數(shù)前加上mutation關(guān)鍵字

mutating func moveH(distance : Double) {
        self.x += distance
 }
結(jié)構(gòu)體的使用
//創(chuàng)建結(jié)構(gòu)體對應(yīng)值
var center = location(x: 20, y: 30)
//調(diào)用函數(shù)修改成員屬性
center.moveH(distance: 20)
//使用自定義構(gòu)造函數(shù)初始化
location(xyStr: "20,30")

swift中的類

類的定義格式
class 類名 : SuperClass {
    //定義屬性和方法
}

和結(jié)構(gòu)體定義類似,但在swift中,類可以繼承一個父類或者不繼承,自己為根類。

類的定義
定義屬性和方法
class Person {
    //存儲屬性
    var name : String = ""
    var score1 : Double = 100
    var score2 : Double = 88
    var score3 : Double = 94
    //計算屬性--> 只讀屬性
    var averageScore : Double {
        return (self.score1 + self.score2 + self.score3) * 0.5
    }
    //類屬性:和這個類相關(guān),并且通過類名進行訪問
    static var courseCount : Int = 0

    //函數(shù)
    func getAverageScore() -> Double {
        return (self.score1 + self.score2 + self.score3) * 0.5
    }
}

與結(jié)構(gòu)體一樣,類中的成員變量需要先初始化。swift中的計算屬性是只讀屬性,我感覺與oc中屬性的get方法類似。oc還有類屬性,直接與類關(guān)聯(lián),我們可以通過類名對它進行訪問

var stu = Student()
//修改成員變量
stu.name = "zzq"
//獲取只讀屬性
print(stu.averageScore)
//修改類屬性
Student.courseCount = 3
類的屬性監(jiān)聽器

當我們類中屬性發(fā)生變化時,我們可以通過屬性監(jiān)聽器來知道屬性即將改變和已經(jīng)改變,并作出相應(yīng)處理

class Person {
    //成員變量需要初始化
    var name : String = "" {
        //監(jiān)聽屬性即將改變,還沒改變
        willSet {
            print(newValue)
            print("即將改變")
        }
        //監(jiān)聽屬性已經(jīng)改變
        didSet {
            print(oldValue)
            print("發(fā)生改變")
        }
    }
}

在屬性后使用括弧,使用willSet方法監(jiān)聽即將改變,didSet方法監(jiān)聽已經(jīng)改變,默認情況下,willSet提供了newVlue參數(shù)告訴我們新的值是什么,didSet提供oldValue參數(shù)告訴我們舊的值是什么。

類的構(gòu)造函數(shù)

與結(jié)構(gòu)體一樣,默認情況下系統(tǒng)會提供默認的構(gòu)造函數(shù),我們也可以自定義構(gòu)造函數(shù),當我們自定義構(gòu)造函數(shù)后,默認的構(gòu)造函數(shù)將無法使用,如果要使用,我們需要手動重寫一下默認的構(gòu)造函數(shù)。

//類的構(gòu)造函數(shù)
class Person {
    var name : String = ""
    var age : Int = 0

    //如果自定義構(gòu)造函數(shù),會覆蓋系統(tǒng)提供的構(gòu)造函數(shù)覆蓋
    init(name : String , age : Int) {
        self.name = name;
        self.age = age
    }
    //重寫系統(tǒng)構(gòu)造函數(shù)
    init() {
        
    }
}
使用KVC

KVC是oc中的一種特性,如果需要在swift類中使用KVC必須滿足以下條件

  • 繼承NSObject類
  • 先調(diào)用super.init()
  • 如果字典中某key沒有對應(yīng)屬性,需要重寫setvalue forundefinekey方法
class Person : NSObject {
    var name : String = ""
    var age : Int = 0

    //使用KVC
    forundefinekey
    init(dict : [String : Any]) {
        super.init()
        setValuesForKeys(dict)
    }
    override func setValue(_ value: Any?, forUndefinedKey key: String) {

    }
}

通過KVC可以快速對類中成員變量進行初始化賦值。

析構(gòu)函數(shù)

與oc類似,swift也是通過引用計數(shù)來判斷對象聲明周期的,當對象銷毀時會調(diào)用類的析構(gòu)函數(shù)。

class Person {
    var name : String = ""
    var age : Int = 0
    //析構(gòu)函數(shù)
    deinit {
        print("對象 銷毀")
    }
}

系統(tǒng)會默認生成析構(gòu)函數(shù),我們也可以重寫deinit方法來處理一些事情

循環(huán)引用

與oc差不多,由于生命周期通過引用計數(shù)管理,當對象之間相互持有時會導致循環(huán)引用,出現(xiàn)內(nèi)存無法釋放的問題。

class Person {
    var name : String = ""
    var book : Book?

    deinit {
        print("person - deinit")
    }
}

class Book {
    weak var owner : Person?

    deinit {
        print("book - deinit")
    }
}

var p : Person? = Person()
var b : Book? = Book()

p!.book = b
b!.owner = p

p = nil
b = nil

為了解決這個問題,我們可以在成員變量前添加weak關(guān)鍵字,這樣就不會產(chǎn)品循環(huán)引用了。

可選鏈

在上一篇類型中我們已經(jīng)知道,為了代碼的嚴謹和安全,對所有可能為nil的對象都是可選類型。為了使用起來更加方便,swift提供了可選鏈方便我們調(diào)用。

class Person {
    var name : String = ""
    var dog : Dog?
}

class Dog {
    var weight : Double = 0.0
    var toy : Toy?
}

class Toy {
    var price : Double = 0
    func flying() -> Void {
        print("飛")
    }
}

let p = Person()
p.name = "zzq"
let d = Dog()
d.weight = 14
let t = Toy()
t.price = 100

p.dog = d
d.toy = t

//?.就是可選鏈,系統(tǒng)自動判斷該可選類型是否有值,如果有值解包,沒有賦值為nil
let price = p.dog?.toy?.price
p.dog?.toy?.flying()

我們可以通過 `?.的格式快速訪問對象中的可選類型。并交給系統(tǒng)進行解包或賦值為nil

協(xié)議

協(xié)議的定義格式
protocol SprortProtocol {
    func play1()
    func play2()
}

在swift中默認情況下,如果遵守了協(xié)議,就必須實現(xiàn)協(xié)議中所有的方法。

class Teacher : SprortProtocol {
    func play1() {
        print("play1")
    }
    func play2() {
        print("play2")
    }
}

如果我們希望協(xié)議中的方法是選擇實現(xiàn)的,我們需要使用到oc中的optional關(guān)鍵字,并且在協(xié)議和方法前添加@objc關(guān)鍵字

@objc protocol SprortProtocol {
    @objc optional func play1()
    func play2()
}

這樣play1方法就不是必須要實現(xiàn)的了

給協(xié)議指定可遵守的類型

在swift中,類,結(jié)構(gòu)體甚至是枚舉都可以遵守協(xié)議。這就讓我們的代碼變得不那么嚴謹,我們可以在協(xié)議名后指定可遵守該協(xié)議的類型來讓我們代碼看起來更嚴謹。

protocol  SprortProtocol: class {
    func buy()
}

這樣,就只有class可以遵守該協(xié)議了。這樣寫往往是用于我們的代理設(shè)計模式。

代理模式
protocol buyDelegate : class {
    func buy()
}

class Person {
    //定義代理屬性
    weak var delegate : buyDelegate?
    func going() {
        self.delegate?.buy()
    }
}

為了防止循環(huán)引用,代理對象前最好添加weak關(guān)鍵字。

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

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

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