Swift教學
Swift快速入門
Swift簡介
Swift基礎
Swift常量和變量
Swift註釋
swift分號
Swift整數
Swift浮點數
Swift類型安全和類型推斷
swift數值型字面量
Swift數值型類型轉換
Swift類型別名
Swift布爾值
Swift元組
Swift可選類型
Swift斷言
Swift基本運算符
Swif哈希集合
Swift運算術語
Swift字典
Swift賦值運算符
Swift數值運算
Swift複合賦值
Swift比較運算
Swift三元條件運算
Swift區間運算符
Swift邏輯運算
Swift字符串和字符
Swift字符串字面量
Swift初始化空字符串
Swift字符串可變性
Swift字符串是值類型
Swift使用字符
Swift計算字符數量
Swift連接字符串和字符
Swift字符串插值
Swift比較字符串
Swift大寫和小寫字符串
Swift Unicode
Swift集合類型 (Collection Types)
Swift數組
Swift字典
Swift集合的可變性
Swift控制流
Swift For循環
Swift While循環
Swift條件語句
Swift控制轉移語句
Swift函數
Swift函數的定義與調用
Swift函數參數與返回值
Swift函數參數名稱
Swift函數類型
Swift嵌套函數
Swift閉包
Swift閉包表達式
Swift尾隨閉包
Swift捕獲值
Swift閉包是引用類型
Swift枚舉
Swift枚舉語法
Swift匹配枚舉值和Switch語句
Swift相關值
Swift原始值
Swift類和結構體
Swift類和結構體對比
Swift結構體和枚舉是值類型
Swift類是引用類型
Swift類和結構體的選擇
Swift集合(Collection)類型的賦值和拷貝行爲
Swift屬性
Swift存儲屬性
Swift計算屬性
Swift屬性監視器
Swift全局變量和局部變量
Swift類型屬性
Swift方法
Swift實例方法
Swift類型方法
Swift下標腳本
Swift下標腳本語法
Swift下標腳本用法
Swift下標腳本選項
Swift繼承
Swift定義一個基類
Swift子類生成
Swift重寫
Swift防止重寫
Swift構造過程
Swift存儲型屬性的初始賦值
Swift定製化構造過程
Swift默認構造器
Swift值類型的構造器代理
Swift類的繼承和構造過程
Swift通過閉包和函數來設置屬性的默認值
Swift析構過程
Swift析構過程原理
Swift析構函數操作
Swift自動引用計數
Swift自動引用計數的工作機制
Swift自動引用計數實踐
Swift類實例之間的循環強引用
Swift解決實例之間的循環強引用
Swift閉包引起的循環強引用
Swift解決閉包引起的循環強引用
Swift可選鏈
Swift可選鏈可替代強制解析
Swift爲可選鏈定義模型類
Swift通過可選鏈調用屬性
Swift通過可選鏈調用方法
Swift使用可選鏈調用子腳本
Swift連接多層鏈接
Swift鏈接可選返回值的方法
Swift類型轉換
Swift定義一個類層次作爲例子
Swift檢查類型
Swift向下轉型
Swift Any和AnyObject類型轉換
Swift嵌套類型
Swift嵌套類型實例
Swift嵌套類型的引用
Swift擴展
Swift擴展語法
Swift計算型屬性
Swift構造器
Swift方法擴展
Swift下標
Swift嵌套類型擴展
Swift協議
Swift協議的語法
Swift屬性要求
Swift方法要求
Swift突變方法要求
Swift協議類型
Swift委託(代理)模式
Swift在擴展中添加協議成員
Swift通過擴展補充協議聲明
Swift集合中的協議類型
Swift協議的繼承
Swift協議合成
Swift檢驗協議的一致性
Swift可選協議要求
Swift泛型
Swift泛型所解決的問題
Swift泛型函數
Swift類型參數
Swift命名類型參數
Swift泛型類型
Swift類型約束
Swift關聯類型
Swift Where語句
Swift高級運算符
Swift位運算符
Swift溢出運算符
Swift優先級和結合性
Swift運算符函數
Swift自定義運算符
Swift語法結構
Swift空白與註釋
Swift標識符
Swift關鍵字
Swift字面量
Swift運算符
Swift類型
Swift類型註解
Swift類型標識符
Swift元組類型
Swift函數類型(參數類型和返回值類型)
Swift數組類型
Swift可選類型(命名型類型)
Swift隱式解析可選類型
Swift協議合成類型
Swift元類型
Swift類型繼承子句
Swift類型推斷
Swift表達式
Swift前綴表達式
Swift二元表達式
Swift賦值表達式
Swift類型轉換運算符
Swift主表達式
Swift後綴表達式
Swift語句
Swift循環語句
Swift For語句
Swift分支語句
Swift帶標籤的語句
Swift聲明
Swift模塊範圍
Swift代碼塊
Swift引入聲明
Swift常量聲明
Swift類型的別名聲明
Swift函數聲明
Swift枚舉聲明
Swift結構體聲明
Swift類聲明
Swift協議聲明
Swift構造器聲明
Swift析構聲明
Swift擴展聲明
Swift下標腳本聲明
Swift運算符聲明
Swift變量聲明
Swift特性
Swift聲明特性
Swift類型特性
Swift模式
Swift通配符模式
Swift標識符模式
Swift值綁定模式
Swift元組模式
Swift枚舉用例模式
Swift類型轉換模式
Swift表達式模式
Swift泛型參數
Swift泛型形參子句
Swift開發環境設置
Swift基本語法
Swift數據類型
Swift變量
Swift常量
Swift字面量
Swift運算符
Swift比較運算符
Swift邏輯運算符
Swift位運算符
Swift賦值運算符
Swift範圍運算符
Swift其它運算符
Swift運算符優先級
Swift算術運算符
Swift if語句
Swift if...else語句
Swift if...else if...else語句
Swift嵌套 if 語句
Swift Switch語句
Swift決策
Swift for-in循環
Swift for循環
Swift while循環
Swift do...while循環
Swift continue語句
Swift break語句
Swift fallthrough語句
Swift循環
Swift字符串
Swift字符
Swift數組
Swift函數
Swift閉包
Swift枚舉
Swift結構體
Swift類
Swift 屬性
Swift 方法
Swift 下標
Swift 繼承
Swift初始化
Swift 反初始化
Swift ARC自動引用計數
Swift 可選鏈
Swift 類型轉換
Swift 擴展
Swift 協議
Swift 泛型
Swift訪問控制

Swift實例方法

實例方法(Instance Methods)

實例方法是屬於某個特定類、結構體或者枚舉類型實例的方法。實例方法提供訪問和修改實例屬性的方法或提供與實例目的相關的功能,並以此來支撐實例的功能。實例方法的語法與函數完全一致,詳情參見函數。

實例方法要寫在它所屬的類型的前後大括號之間。實例方法能夠隱式訪問它所屬類型的所有的其他實例方法和屬性。實例方法只能被它所屬的類的某個特定實例調用。實例方法不能脫離於現存的實例而被調用。

下面的例子,定義一個很簡單的類CounterCounter能被用來對一個動作發生的次數進行計數:

class Counter {
  var count = 0
  func increment() {
    count++
  }
  func incrementBy(amount: Int) {
    count += amount
  }
  func reset() {
    count = 0
  }
}

Counter類定義了三個實例方法:

  • increment讓計數器按一遞增;
  • incrementBy(amount: Int)讓計數器按一個指定的整數值遞增;
  • reset將計數器重置爲0。

Counter這個類還聲明瞭一個可變屬性count,用它來保持對當前計數器值的追蹤。

和調用屬性一樣,用點語法(dot syntax)調用實例方法:

 let counter = Counter()
 // 初始計數值是0
 counter.increment()
 // 計數值現在是1
 counter.incrementBy(5)
 // 計數值現在是6
 counter.reset()
 // 計數值現在是0

方法的局部參數名稱和外部參數名稱(Local and External Parameter Names for Methods)

函數參數可以同時有一個局部名稱(在函數體內部使用)和一個外部名稱(在調用函數時使用),詳情參見函數的外部參數名。方法參數也一樣(因爲方法就是函數,只是這個函數與某個類型相關聯了)。但是,方法和函數的局部名稱和外部名稱的默認行爲是不一樣的。

Swift 中的方法和 Objective-C 中的方法極其相似。像在 Objective-C 中一樣,Swift 中方法的名稱通常用一個介詞指向方法的第一個參數,比如:withforby等等。前面的Counter類的例子中incrementBy方法就是這樣的。介詞的使用讓方法在被調用時能像一個句子一樣被解讀。和函數參數不同,對於方法的參數,Swift 使用不同的默認處理方式,這可以讓方法命名規範更容易寫。

具體來說,Swift 默認僅給方法的第一個參數名稱一個局部參數名稱;默認同時給第二個和後續的參數名稱局部參數名稱和外部參數名稱。這個約定與典型的命名和調用約定相適應,與你在寫 Objective-C 的方法時很相似。這個約定還讓表達式方法在調用時不需要再限定參數名稱。

看看下面這個Counter的另一個版本(它定義了一個更復雜的incrementBy方法):

class Counter {
  var count: Int = 0
  func incrementBy(amount: Int, numberOfTimes: Int) {
    count += amount * numberOfTimes
  }
}

incrementBy方法有兩個參數: amountnumberOfTimes。默認情況下,Swift 只把amount當作一個局部名稱,但是把numberOfTimes即看作局部名稱又看作外部名稱。下面調用這個方法:

let counter = Counter()
counter.incrementBy(5, numberOfTimes: 3)
// counter value is now 15

你不必爲第一個參數值再定義一個外部變量名:因爲從函數名incrementBy已經能很清楚地看出它的作用。但是第二個參數,就要被一個外部參數名稱所限定,以便在方法被調用時明確它的作用。

這種默認的行爲能夠有效的處理方法(method),類似於在參數numberOfTimes前寫一個井號(#):

func incrementBy(amount: Int, #numberOfTimes: Int) {
  count += amount * numberOfTimes
}

這種默認行爲使上面代碼意味着:在 Swift 中定義方法使用了與 Objective-C 同樣的語法風格,並且方法將以自然表達式的方式被調用。

修改方法的外部參數名稱(Modifying External Parameter Name Behavior for Methods)

有時爲方法的第一個參數提供一個外部參數名稱是非常有用的,儘管這不是默認的行爲。你可以自己添加一個顯式的外部名稱或者用一個井號(#)作爲第一個參數的前綴來把這個局部名稱當作外部名稱使用。

相反,如果你不想爲方法的第二個及後續的參數提供一個外部名稱,可以通過使用下劃線(_)作爲該參數的顯式外部名稱,這樣做將覆蓋默認行爲。

self屬性(The self Property)

類型的每一個實例都有一個隱含屬性叫做selfself完全等同於該實例本身。你可以在一個實例的實例方法中使用這個隱含的self屬性來引用當前實例。

上面例子中的increment方法還可以這樣寫:

func increment() {
  self.count++
}

實際上,你不必在你的代碼裏面經常寫self。不論何時,只要在一個方法中使用一個已知的屬性或者方法名稱,如果你沒有明確的寫self,Swift 假定你是指當前實例的屬性或者方法。這種假定在上面的Counter中已經示範了:Counter中的三個實例方法中都使用的是count(而不是self.count)。

使用這條規則的主要場景是實例方法的某個參數名稱與實例的某個屬性名稱相同的時候。在這種情況下,參數名稱享有優先權,並且在引用屬性時必須使用一種更嚴格的方式。這時你可以使用self屬性來區分參數名稱和屬性名稱。

下面的例子中,self消除方法參數x和實例屬性x之間的歧義:

struct Point {
  var x = 0.0, y = 0.0
  func isToTheRightOfX(x: Double) -> Bool {
    return self.x > x
  }
}
let somePoint = Point(x: 4.0, y: 5.0)
if somePoint.isToTheRightOfX(1.0) {
  println("This point is to the right of the line where x == 1.0")
}
// 輸出 "This point is to the right of the line where x == 1.0"(這個點在x等於1.0這條線的右邊)

如果不使用self前綴,Swift 就認爲兩次使用的x都指的是名稱爲x的函數參數。

在實例方法中修改值類型(Modifying Value Types from Within Instance Methods)

結構體和枚舉是值類型。一般情況下,值類型的屬性不能在它的實例方法中被修改。

但是,如果你確實需要在某個具體的方法中修改結構體或者枚舉的屬性,你可以選擇變異(mutating)這個方法,然後方法就可以從方法內部改變它的屬性;並且它做的任何改變在方法結束時還會保留在原始結構中。方法還可以給它隱含的self屬性賦值一個全新的實例,這個新實例在方法結束後將替換原來的實例。

要使用變異方法, 將關鍵字mutating 放到方法的func關鍵字之前就可以了:

struct Point {
  var x = 0.0, y = 0.0
  mutating func moveByX(deltaX: Double, y deltaY: Double) {
    x += deltaX
    y += deltaY
  }
}
var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveByX(2.0, y: 3.0)
println("The point is now at (\(somePoint.x), \(somePoint.y))")
// 輸出 "The point is now at (3.0, 4.0)"

上面的Point結構體定義了一個變異方法(mutating method)moveByXmoveByX用來移動點。moveByX方法在被調用時修改了這個點,而不是返回一個新的點。方法定義時加上mutating關鍵字,這才讓方法可以修改值類型的屬性。

注意:不能在結構體類型常量上調用變異方法,因爲常量的屬性不能被改變,即使想改變的是常量的變量屬性也不行,詳情參見存儲屬性和實例變量

let fixedPoint = Point(x: 3.0, y: 3.0)
fixedPoint.moveByX(2.0, y: 3.0)
// this will report an error

在變異方法中給self賦值(Assigning to self Within a Mutating Method)

變異方法能夠賦給隱含屬性self一個全新的實例。上面Point的例子可以用下面的方式改寫:

struct Point {
  var x = 0.0, y = 0.0
  mutating func moveByX(deltaX: Double, y deltaY: Double) {
    self = Point(x: x + deltaX, y: y + deltaY)
  }
}

新版的變異方法moveByX創建了一個新的結構(它的 x 和 y 的值都被設定爲目標值)。調用這個版本的方法和調用上個版本的最終結果是一樣的。

枚舉的變異方法可以把self設置爲相同的枚舉類型中不同的成員:

enum TriStateSwitch {
  case Off, Low, High
  mutating func next() {
    switch self {
    case Off:
      self = Low
    case Low:
      self = High
    case High:
      self = Off
    }
  }
}
var ovenLight = TriStateSwitch.Low
ovenLight.next()
// ovenLight 現在等於 .High
ovenLight.next()
// ovenLight 現在等於 .Off

上面的例子中定義了一個三態開關的枚舉。每次調用next方法時,開關在不同的電源狀態(OffLowHigh)之前循環切換。