Swift 5.1 (9) - 結構體和類

級別: ★☆☆☆☆
標籤:「iOS」「Swift 5.1」「結構體」「類」「mutating」
做者: 沐靈洛
審校: QiShare團隊php


結構體和類

結構體和類是多功能的,靈活的結構,是程序中代碼的構建塊。咱們可使用與定義常量,變量和函數相同的語法來定義屬性和方法,爲咱們的結構體和類添加功能。 Swift中咱們爲自定義的結構體和類不須要建立單獨的.h和.m文件。而是在單個文件中定義結構體或類便可,而且Swift會提供額外的接口,自動讓類或結構體在其餘代碼中可用。git

比較結構體和類

在Swift中,結構體和類有許多相像的地方。github

  • 定義存儲值的屬性
  • 定義提供功能的方法
  • 定義下標以使用下標語法提供對其值進行訪問
  • 定義初始化方法以設置其初始狀態
  • 能夠被擴展 extend,在函數的默認實現的基礎上能夠擴展其功能。
  • 能夠遵照協議以提供某種標準功能

同時,類具備結構體所沒有的附加功能:編程

  • 繼承:一個類可以繼承另外一個類的特性。
  • 類型轉換:在運行時檢查和解釋類的實例對象所屬類型。
  • 析構函數(Deinitializers):容許類的實例對象釋放它已分配的任何資源。
  • 引用計數:容許對類實例進行多個引用。

語法定義swift

結構和類具備類似的定義語法。使用struct關鍵字定義一個結構體。使用class關鍵字定義類。數組

struct SomeStructure {
}
class SomeClass {
}
複製代碼

結構體和類的實例bash

結構和類構建新實例的最簡單的初始化語法:使用類或結構體的類型名稱,後跟空括號。微信

struct Resolution {
    var width = 0
    var height = 0
    
}
class VideoMode {
    var resolution = Resolution()
    var interlaced = false
    var frameRate = 0.0
    var name: String?
}
let someResolution = Resolution()
let someVideoMode = VideoMode()
複製代碼

屬性訪問閉包

使用**.**語法進行結構體和類的屬性的訪問app

let width = someResolution.width
let width = someVideoMode.resolution.width 
複製代碼

使用**.**語法爲屬性賦新值

someResolution.width = 250
someVideoMode.resolution.width  = 255
複製代碼

結構體類型的成員初始化方法

全部結構體都有一個自動生成的初始化方法。咱們可使用這個自動生成的初始化方法初始化一個新的實例對象,並根據初始化方法的參數(結構體中定義的屬性名稱),設置成員的屬性。

let someResolution = Resolution(width: 33, height: 77)
複製代碼

與結構體不一樣,類沒有默認的成員初始化方法。

結構體和枚舉是值類型

相似Swift中的整數,浮點數,布爾值,字符串,數組和字典,都是值類型的,而且這些類型在Swift中的實現都是基於結構體的。故全部結構體和枚舉值類型都是值類型。這意味着咱們建立的任何結構體和枚舉實例以及做爲它們屬性的任何值類型,在代碼中傳遞時始終會被複制。 注意:標準庫定義的集合,如:數組,字典和字符串使用優化來下降複製的性能成本。這些集合類型不是當即複製,而是共享內存,其元素存儲在原始實例和任何副本之間。若是須要修改集合的其中一個副本,則會在修改以前複製集合中的全部元素。可是咱們在代碼中看到的好像老是當即發生了複製。

let someResolution = Resolution(width: 33, height: 77)
var myResolution = someResolution
複製代碼

在這個賦值的過程當中,因爲Resolution是值類型的,因此首先會生成someResolution實例的副本並將此副本賦值給myResolution。此時someResolutionmyResolution具備相同的寬度和高度,可是倒是兩個不一樣的實例。

myResolution.width = 255
複製代碼

someResolutionmyResolution是兩個單獨的實例,因此修改副本myResolution的屬性width,並不會影響someResolutionwidth。 枚舉類型也是值類型,具備和結構體同樣的賦值特性:複製

enum CompassPoint {
    case north, south, east, west
     mutating func turnNorth() -> Void {
        self = .north
    }
}
var currentDirection = CompassPoint.west
let rememberedDirection = currentDirection
currentDirection.turnNorth()

print("當前的方向,被改變後 \(currentDirection)")//!< 當前的方向,被改變後 north
print("保存的方向 \(rememberedDirection)")//!< 保存的方向 west
複製代碼

使用mutating關鍵字放在枚舉或結構體中所定義方法的func關鍵字以前,使得該方法能夠在方法中修改枚舉或結構體的屬性。 當currentDirection賦值給rememberedDirection時,rememberedDirection擁有的是currentDirection實例的副本。此後更改currentDirection的值不會影響存儲在rememberedDirection中值。由於彼此獨立。

類是引用類型的

與值類型不一樣,引用類型在分配給變量或常量時或者傳遞給函數時不會被複制,而是使用對同一實例的引用。

let tenEighty = VideoMode()
tenEighty.resolution = someResolution
tenEighty.interlaced = true
tenEighty.name = "視頻模式"
tenEighty.frameRate = 25.0
//賦值給新的實例對象
let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0
print(tenEighty.frameRate,alsoTenEighty.frameRate)
//!< tenEighty.frameRate:30.0 alsoTenEighty.frameRate:30
複製代碼

身份運算符

參考swift 5.1基礎(二)運算符講解。

指針

Swift中引用某個引用類型的實例做爲常量或變量時,相似於C中的指針,但它不是指向內存中地址的直接指針(不是直接尋址),而且不須要編寫星號*來指示你正在建立一個引用對象。相反,這些引用的定義與Swift中的任何其餘常量或變量同樣。 另:Swift標準庫提供指針和緩衝類型,若是須要直接與指針交互,可使用它們 手動內存管理

參考資料: swift 5.1官方編程指南


瞭解更多iOS及相關新技術,請關注咱們的公衆號:

小編微信:可加並拉入《QiShare技術交流羣》。

關注咱們的途徑有:
QiShare(簡書)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公衆號)

推薦文章:
Swift 實現一個兼容iOS、tvOS、OSX的抽象層
iOS Password AutoFill
iOS 給UILabel添加點擊事件
用SwiftUI給視圖添加動畫
用SwiftUI寫一個簡單頁面
Swift 5.1 (7) - 閉包 iOS App啓動優化(三)—— 本身作一個工具監控App的啓動耗時
iOS App啓動優化(二)—— 使用「Time Profiler」工具監控App的啓動耗時
iOS App啓動優化(一)—— 瞭解App的啓動流程
奇舞週刊

相關文章
相關標籤/搜索