Swift類型方法
類型方法(Type Methods)
實例方法是被類型的某個實例調用的方法。你也可以定義類型本身調用的方法,這種方法就叫做類型方法。聲明類的類型方法,在方法的func
關鍵字之前加上關鍵字class
;聲明結構體和枚舉的類型方法,在方法的func
關鍵字之前加上關鍵字static
。
注意:
在 Objective-C 裏面,你只能爲 Objective-C 的類定義類型方法(type-level methods)。在 Swift 中,你可以爲所有的類、結構體和枚舉定義類型方法:每一個類型方法都被它所支持的類型顯式包含。
類型方法和實例方法一樣用點語法調用。但是,你是在類型層面上調用這個方法,而不是在實例層面上調用。下面是如何在SomeClass
類上調用類型方法的例子:
class SomeClass {
class func someTypeMethod() {
// type method implementation goes here
}
}
SomeClass.someTypeMethod()
在類型方法的方法體(body)中,self
指向這個類型本身,而不是類型的某個實例。對於結構體和枚舉來說,這意味着你可以用self
來消除靜態屬性和靜態方法參數之間的歧義(類似於我們在前面處理實例屬性和實例方法參數時做的那樣)。
一般來說,任何未限定的方法和屬性名稱,將會來自於本類中另外的類型級別的方法和屬性。一個類型方法可以調用本類中另一個類型方法的名稱,而無需在方法名稱前面加上類型名稱的前綴。同樣,結構體和枚舉的類型方法也能夠直接通過靜態屬性的名稱訪問靜態屬性,而不需要類型名稱前綴。
下面的例子定義了一個名爲LevelTracker
結構體。它監測玩家的遊戲發展情況(遊戲的不同層次或階段)。這是一個單人遊戲,但也可以存儲多個玩家在同一設備上的遊戲信息。
遊戲初始時,所有的遊戲等級(除了等級 1)都被鎖定。每次有玩家完成一個等級,這個等級就對這個設備上的所有玩家解鎖。LevelTracker
結構體用靜態屬性和方法監測遊戲的哪個等級已經被解鎖。它還監測每個玩家的當前等級。
struct LevelTracker {
static var highestUnlockedLevel = 1
static func unlockLevel(level: Int) {
if level > highestUnlockedLevel { highestUnlockedLevel = level }
}
static func levelIsUnlocked(level: Int) -> Bool {
return level <= highestUnlockedLevel
}
var currentLevel = 1
mutating func advanceToLevel(level: Int) -> Bool {
if LevelTracker.levelIsUnlocked(level) {
currentLevel = level
return true
} else {
return false
}
}
}
LevelTracker
監測玩家的已解鎖的最高等級。這個值被存儲在靜態屬性highestUnlockedLevel
中。
LevelTracker
還定義了兩個類型方法與highestUnlockedLevel
配合工作。第一個類型方法是unlockLevel
:一旦新等級被解鎖,它會更新highestUnlockedLevel
的值。第二個類型方法是levelIsUnlocked
:如果某個給定的等級已經被解鎖,它將返回true
。(注意:儘管我們沒有使用類似LevelTracker.highestUnlockedLevel
的寫法,這個類型方法還是能夠訪問靜態屬性highestUnlockedLevel
)
除了靜態屬性和類型方法,LevelTracker
還監測每個玩家的進度。它用實例屬性currentLevel
來監測玩家當前的等級。
爲了便於管理currentLevel
屬性,LevelTracker
定義了實例方法advanceToLevel
。這個方法會在更新currentLevel
之前檢查所請求的新等級是否已經解鎖。advanceToLevel
方法返回布爾值以指示是否能夠設置currentLevel
。
下面,Player
類使用LevelTracker
來監測和更新每個玩家的發展進度:
class Player {
var tracker = LevelTracker()
let playerName: String
func completedLevel(level: Int) {
LevelTracker.unlockLevel(level + 1)
tracker.advanceToLevel(level + 1)
}
init(name: String) {
playerName = name
}
}
Player
類創建一個新的LevelTracker
實例來監測這個用戶的發展進度。它提供了completedLevel
方法:一旦玩家完成某個指定等級就調用它。這個方法爲所有玩家解鎖下一等級,並且將當前玩家的進度更新爲下一等級。(我們忽略了advanceToLevel
返回的布爾值,因爲之前調用LevelTracker.unlockLevel
時就知道了這個等級已經被解鎖了)。
你還可以爲一個新的玩家創建一個Player
的實例,然後看這個玩家完成等級一時發生了什麼:
var player = Player(name: "Argyrios")
player.completedLevel(1)
println("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)")
// 輸出 "highest unlocked level is now 2"(最高等級現在是2)
如果你創建了第二個玩家,並嘗試讓它開始一個沒有被任何玩家解鎖的等級,那麼這次設置玩家當前等級的嘗試將會失敗:
player = Player(name: "Beto")
if player.tracker.advanceToLevel(6) {
println("player is now on level 6")
} else {
println("level 6 has not yet been unlocked")
}
// 輸出 "level 6 has not yet been unlocked"(等級6還沒被解鎖)