<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## Swift 屬性和方法 在Swift中,構建結構體或者類屬性和方法中,它們分為:存儲型屬性、計算型屬性和靜態屬性。 ### 計算型屬性 ``` struct Point { var x = 0.0 // 存儲型屬性 var y = 0.0 } struct Size { var width = 0.0 // 存儲型屬性 var height = 0.0 } class Rectangle { var origin = Point() // 存儲型屬性 var size = Size() // 計算性屬性,必須聲明稱變量,因為它的值是根據其他屬性的值計算得出。 // 另外,計算型屬性必須聲明數據類型,否則將會報錯 (error: computed property must have an explicit type) var center: Point { // getter get { let centerX = origin.x + size.width / 2 let centerY = origin.y + size.height / 2 return Point(x: centerX , y: centerY) } // setter set { origin.x = newValue.x - size.width / 2 // newValue 是要傳遞給center計算性屬性的新值 origin.y = newValue.y - size.height / 2 } } // 計算性屬性,只有 getter 即只讀屬性(無setter)。 var area: Double { return size.width * size.height } init (origin: Point , size: Size){ self.origin = origin self.size = size } } var rect = Rectangle( origin: Point(), size: Size(width: 10 , height: 5) ) rect.center rect.origin = Point(x: 10 , y: 10) print( rect.center ) // 改變計算型屬性值 rect.center = Point() rect ``` ### 靜態屬性 使用 `static` 關鍵字聲明靜態屬性,該屬性定義在類型屬性上的Type Property。靜態屬性存儲在類型中,不是存儲在類的實例化對象上 ``` class Player { var name: String // 存儲型屬性 var score: UInt32 = 0 static var highestScore: UInt32 = 0 // 使用關鍵字static聲明靜態屬性,存儲最高分 init(name: String) { // 構造函數中給存儲型屬性賦值 self.name = name } func play() { let score = arc4random() % 100 print("\(self.name) played and got \(score) scores.") self.score += score print("Total score of \(self.name) is \(self.score)") if self.score > Player.highestScore { // 使用類自身調用靜態變量,而不是使用self調用自己的靜態屬性并且也不能省略Player的書寫 Player.highestScore = self.score } print("Highest scores is \(Player.highestScore)") } } let player1 = Player(name: "Player1") let player2 = Player(name: "Player2") player1.play() // 玩一局得分 player1.play() // 玩第二局得分 player2.play() player2.play() player2.play() ``` ### 類型方法 靜態方法 定義在整個類型上的靜態方法。 ``` struct Matrix{ var m: [[Int]] var row: Int var col: Int init?(_ arr2d: [[Int]]){ guard arr2d.count > 0 else{ return nil } let row = arr2d.count let col = arr2d[0].count for i in 1..<row{ if arr2d[i].count != col{ return nil } } self.m = arr2d self.row = row self.col = col } func printMatrix() { for i in 0 ..< row { for j in 0 ..< col { print(m[i][j],terminator:"\t") } print() } } static func identityMatrix(n: Int) -> Matrix? { // 靜態方法 if n <= 0 { return nil } var arr2d:[[Int]] = [] for i in 0 ..< n { var row = [Int](repeating: 0, count: n) row[i] = 1 arr2d.append(row) } return Matrix(arr2d)! } } if let m = Matrix([[1,2,],[3,4]]){ m.printMatrix() } if let e = Matrix.identityMatrix(n: 8) { e.printMatrix() } ``` ### 屬性觀察器 如果外部修改了類中的成員屬性操作類的 `static` 靜態屬性大小,可以通過關鍵字限制。可以通過關鍵字 `didSet`、`willSet` 進行邏輯判斷。 ``` class LightBulb{ static let maxCurrent = 30 var current = 0 { willSet { // 在對象中賦值 current 之前,{} 中的邏輯代碼將執行 print("Current value changed. The Change is \(abs(current - newValue))") } didSet{ // 在對象中賦值 current 完成,{} 中的邏輯代碼將執行 if self.current == LightBulb.maxCurrent { print("Pay attention, the current value get to the maximum point.") }else if self.current > LightBulb.maxCurrent{ print("Current too height , falling back to previous setting.") self.current = oldValue } print("The current is \(self.current)") } } } let bulb = LightBulb() bulb.current = 20 bulb.current = 30 bulb.current = 40 ``` > 屬性觀察器經常應用在保護數據是否合法的場景中。 > 注意: `didSet` 和 `willSet` 不會在初始化階段調用。 如下Demo: ``` enum Theme { case DayMode case NightMode } class UI{ var fontColor: UIColor! var backgroundColor: UIColor! var themeMode: Theme = .DayMode { didSet{ switch themeMode { case .DayMode: fontColor = UIColor.black backgroundColor = UIColor.white case.NightMode: fontColor = UIColor.white backgroundColor = UIColor.black } } } init(themeMode: Theme) { self.themeMode = themeMode } } let ui = UI(themeMode: Theme.DayMode) ui.themeMode ui.fontColor // nil ui.backgroundColor // nil ``` 我們查看到 `ui.fontColor` 和 `ui.backgroundColor` 的值為 `nil` 。說明在執行初始化的時候并沒有調用 `didSet` ,應該進行如下代碼改進。 ``` enum Theme { case DayMode case NightMode } class UI{ var fontColor: UIColor! var backgroundColor: UIColor! var themeMode: Theme = .DayMode { didSet{ self.chengeTheme(themeMode: themeMode) } } init(themeMode: Theme) { self.themeMode = themeMode self.chengeTheme(themeMode: themeMode) } func chengeTheme(themeMode: Theme) { switch themeMode { case .DayMode: fontColor = UIColor.black backgroundColor = UIColor.white case.NightMode: fontColor = UIColor.white backgroundColor = UIColor.black } } } let ui = UI(themeMode: Theme.DayMode) ui.themeMode ui.fontColor // nil ui.backgroundColor // nil ``` ### 惰性加載(延遲加載) 很多時候我們有這種需求,當我們有一個大計算量的屬性需要計算,我們會將邏輯放在構造函數中,可能使用這個計算型屬性的情況不多。每次實例化都需要重新計算這個屬性,這樣會導致性能的浪費。 我們也可以把這個計算邏輯放入到計算型屬性中,那假如用戶經常調用的話就會一次又一次的重新計算。 為了調節這中矛盾。Swift為我們發明了一種 Lazy Property ,延遲屬性。 ``` class ClosedRange { let start: Int let end: Int var width: Int{ return end - start + 1 } lazy var sum: Int = { // 計算型延遲加載 var res = 0 for i in self.start ... self.end{ res += i } return res }() // 延遲性屬性閉包的調用 init?( start: Int , end: Int ) { if start > end { return nil } self.start = start self.end = end } } if let range = ClosedRange(start: 0, end: 10_000){ range.width range.sum // 第一次調用會計算 range.sum // 重復調用不會多次計算屬性值 range.sum } ``` > `lazy` 關鍵字不允許使用在常量屬性上。 #### 惰性加載的一些其他場景 ``` // 根據經緯度計算地理位置 class Location { let latitude: Double let longitude: Double lazy var address: String? = { return nil }() init(latitude: Double , longitude: Double){ self.latitude = latitude self.longitude = longitude } } // 圖書、電影、音樂相關App class Book { let name: String lazy var content: String? = { // 從本地讀取書的內容 return nil }() init(name: String){ self.name = name } } // Web請求 class Web { let url: String lazy var html: String? = { // 從網絡讀取url對應的html return nil }() init(url: String) { self.url = url } } ``` ### 訪問控制 Swift 的訪問控制是通過**文件**為單位控制的。其中: * public 可以被模塊外訪問 * internal 可以被本模塊訪問,當我們不顯式指定的時候,所有的類、屬性或者方法的訪問權限都是 **internal** 。 * private 可以被本文件訪問 例如:`Sources` 目錄下 `Ui.swift` 文件內容如下: ``` enum Theme { case DayMode case NightMode } class UI{ private var fontColor: UIColor! private var backgroundColor: UIColor! var themeMode: Theme = .DayMode { didSet{ self.chengeTheme(themeMode: themeMode) } } init(){ self.themeMode = .DayMode self.chengeTheme(themeMode: self.themeMode) } init(themeMode: Theme) { self.themeMode = themeMode self.chengeTheme(themeMode: themeMode) } private func chengeTheme(themeMode: Theme) { switch themeMode { case .DayMode: fontColor = UIColor.black backgroundColor = UIColor.white case .NightMode: fontColor = UIColor.white backgroundColor = UIColor.black } } func show() { print("The font color is \(self.fontColor == UIColor.white ? "BLACK" : "WHITE")") print("The background color is \(self.backgroundColor == UIColor.black ? "WHITE" : "BLACK")") } } ``` `Sources` 目錄下 `App.swift` 文件中定義相關的結構或者類,內容如下: ``` import Foundation public class App{ private let ui = UI() public var name: String public init(name: String) { self.name = name } public func switchMode() { switch ui.themeMode { case Theme.DayMode: ui.themeMode = Theme.NightMode case Theme.NightMode: ui.themeMode = Theme.DayMode } } public func show() { print("The App name is \(self.name)") ui.show() } } ``` ### 單例模式 有兩個文件,`gameManager.swift` 是一個單例類。 ``` import Foundation public class GameManager { public var score = 0 public static let defaltGameManager = GameManager() // 自己初始化自己 private init(){ } public func addScore(){ self.score += 10 } } ``` > 注意: 初始化函數設置為 `private` ,`defaultGameManager` 設置為靜態常量。 ``` import UIKit let gameManager = GameManager.defaltGameManager // 不允許實例化 GameManager,只能通過GameManager的靜態屬性 defaltGameManager 獲得 GameManager 的實例 gameManager.addScore() gameManager.score // 10 let gm = GameManager.defaltGameManager gm.addScore() gm.score // 20 ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看