版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2017.07.29 |
前言
我是swift2.0的時候開始接觸的江锨,記得那時候還不是很穩(wěn)定贞言,公司的項目也都是用oc做的斜棚,并不對swift很重視,我自己學(xué)了一段時間该窗,到現(xiàn)在swift3.0+已經(jīng)出來了弟蚀,自己平時也不寫,忘記的也差不多了酗失,正好項目這段時間已經(jīng)上線了粗梭,不是很忙,我就可以每天總結(jié)一點了级零,希望對自己對大家有所幫助断医。在總結(jié)的時候我會對比oc進行說明,有代碼的我會給出相關(guān)比對代碼奏纪。
1. swift簡單總結(jié)(一)—— 數(shù)據(jù)簡單值和類型轉(zhuǎn)換
2. swift簡單總結(jié)(二)—— 簡單值和控制流
3. swift簡單總結(jié)(三)—— 循環(huán)控制和函數(shù)
4. swift簡單總結(jié)(四)—— 函數(shù)和類
5. swift簡單總結(jié)(五)—— 枚舉和結(jié)構(gòu)體
6. swift簡單總結(jié)(六)—— 協(xié)議擴展與泛型
7. swift簡單總結(jié)(七)—— 數(shù)據(jù)類型
8. swift簡單總結(jié)(八)—— 別名鉴嗤、布爾值與元組
9. swift簡單總結(jié)(九)—— 可選值和斷言
10. swift簡單總結(jié)(十)—— 運算符
11. swift簡單總結(jié)(十一)—— 字符串和字符
12. swift簡單總結(jié)(十二)—— 集合類型之?dāng)?shù)組
13. swift簡單總結(jié)(十三)—— 集合類型之字典
14. swift簡單總結(jié)(十四)—— 控制流
15. swift簡單總結(jié)(十五)—— 控制轉(zhuǎn)移語句
16. swift簡單總結(jié)(十六)—— 函數(shù)
17. swift簡單總結(jié)(十七)—— 閉包(Closures)
18. swift簡單總結(jié)(十八)—— 枚舉
19. swift簡單總結(jié)(十九)—— 類和結(jié)構(gòu)體
20. swift簡單總結(jié)(二十)—— 屬性
方法
??大家還記得OC
中的方法吧,包括對象方法和類方法序调。在swift
中同樣有方法醉锅,方法是某些特定類型相關(guān)聯(lián)的函數(shù)。類发绢、結(jié)構(gòu)體和枚舉都可以定義實例方法硬耍,實例方法為給定類型的實例封裝了具體的任務(wù)和功能垄琐。類、結(jié)構(gòu)體和枚舉也可以定義類型方法经柴,類型方法與類型相關(guān)聯(lián)狸窘,與OC
中的類方法相似。
??結(jié)構(gòu)體和枚舉能定義方法是swift
與OC
的主要區(qū)別坯认,在OC
中翻擒,類是唯一能夠定義方法的類型,但是在swift
中牛哺,你可以選擇是否定義一個類陋气、結(jié)構(gòu)體還是枚舉,還能靈活的在你定義的類引润、結(jié)構(gòu)體巩趁、枚舉中定義方法。
本篇文章主要從下面進行講述:
- 實例方法
(Instance Methods)
-
self
屬性 - 類型方法
(Type Methods)
實例方法
??實例方法屬于某一個特定的類淳附、結(jié)構(gòu)體或者枚舉類型實例方法议慰,實例方法提供訪問和修改實例屬性的方法或提供與實例目的相關(guān)的功能,并以此支撐實例的功能燃观,實例方法的語法與函數(shù)完全一致褒脯。
??實例方法要寫在它所屬的類型前后大括號之間便瑟,實例方法能夠隱式訪問它所屬類型的所有其他實例方法和屬性缆毁,實例方法只能被它所屬的類的某個特定實例調(diào)用,實例方法不能脫離于現(xiàn)存的實例而被調(diào)用到涂。
下面看一個例子脊框。
class JJSwiftVC: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
let counter = Counter()
counter.increment()
counter.incrementBy(step: 10)
counter.rest()
}
}
class Counter {
var count = 0
func increment() {
count += 1
print(count)
}
func incrementBy(step : Int) {
count += step
print(count)
}
func rest() {
count = 0
print(count)
}
}
下面看輸出結(jié)果
1
11
0
這里類Counter
定義了三個方法func increment()
、func incrementBy(step : Int)
践啄、func rest()
浇雹。
1. 方法的局部參數(shù)名稱和外部參數(shù)名稱 - Local and External Parameter Names for Methods
??講解函數(shù)的時候,我們知道函數(shù)可以同時有一個局部名稱(在函數(shù)體內(nèi)部使用)和一個外部名稱(在調(diào)用函數(shù)時使用)屿讽。方法參數(shù)也是一樣的昭灵,但是方法和函數(shù)的局部名稱和外部名稱的默認(rèn)行為是不一樣的。
??方法參數(shù)列表與OC
很類似伐谈,你不必定義成外部參數(shù)烂完,swift
會默認(rèn)方法的參數(shù)為外部參數(shù),下面看一下例子诵棵。
class JJSwiftVC: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
let counter = Counter()
counter.incrementBy(amount: 10, numberOfTimes: 5)
}
}
class Counter {
var count : Int = 0
func incrementBy(amount : Int, numberOfTimes : Int) {
count += amount * numberOfTimes
print(count)
}
}
下面看輸出結(jié)果
50
這里抠蚣,大家注意下:
counter.incrementBy(amount: 10, numberOfTimes: 5)
調(diào)用的時候都默認(rèn)兩個參數(shù)都有外部參數(shù)了。
self 屬性
??類型的每一個實例都有一個隱含屬性叫做self
履澳,self
完全等同于該實例本身嘶窄,你可以在一個實例的實例方法中使用這個隱含的self
屬性來引用當(dāng)前實例怀跛。
上面的例子可以改寫為:
class Counter {
var count : Int = 0
func incrementBy(amount : Int, numberOfTimes : Int) {
self.count += amount * numberOfTimes
print(count)
}
}
可見,增加了self也是可以的柄冲。
self.count += amount * numberOfTimes
這里吻谋,self
不是必須的,swift
假定你是指當(dāng)前實例的屬性或者方法羊初。但是有的時候self
有它好用的地方滨溉。
struct Point {
var x = 0.0
var y = 0.0
func isToTheRightOfX(x : Double) -> Bool {
print(self.x)
print(x)
return self.x > x
}
}
class JJSwiftVC: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
let somePoint = Point(x: 4.0, y: 5.0)
if somePoint.isToTheRightOfX(x: 1.0) {
print("This point is to the right of the line where x == 1.0")
}
}
}
下面看輸出結(jié)果
4.0
1.0
This point is to the right of the line where x == 1.0
??這種情況使用self
就有用了,如果不使用self
长赞,swift
就認(rèn)為兩次使用的x
都是指的是名稱為x
的函數(shù)參數(shù)晦攒。但是這個情況完全可以避免,我們可以定義函數(shù)參數(shù)的時候不與結(jié)構(gòu)體成員變量重復(fù)得哆,容易引起歧義脯颜,代碼的可讀性也會差很多。
1. 在實例方法中修改值類型 - Modifying Values Types from Within Instance Methods
??結(jié)構(gòu)體和枚舉都是值類型贩据,值類型的屬性不能再它的實例方法中修改栋操。但是,如果你確實需要在某個具體方法中修改結(jié)構(gòu)體或者枚舉的屬性饱亮,你可以選擇使用變異mutating
這個方法矾芙,然后方法就可以從方法內(nèi)部改變它的屬性,并且它做的任何改變在方法結(jié)束時還保留在原始結(jié)構(gòu)中近上。方法還可以給它隱含self
屬性賦值一個全新的實例剔宪,這個新實例在方法結(jié)束后將替換原來的實例。
下面看代碼壹无。
struct Point {
var x = 0.0
var y = 0.0
mutating func movePoint(deltaX : Double, deltaY : Double) {
x += deltaX
y += deltaY
print("(\(x),\(y))")
}
}
class JJSwiftVC: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
var somePoint = Point(x : 1.0, y : 2.0)
somePoint.movePoint(deltaX: 5.0, deltaY: 5.0)
}
}
下面看輸出結(jié)果
(6.0,7.0)
還有一點葱绒,下面的必須定義為變量var
,才可以修改斗锭。
var somePoint = Point(x : 1.0, y : 2.0)
如果修改成let
就會報錯地淀,即使想改變常量的變量屬性也不可以。
2. 在變異方法中給self賦值 - Assigning to self within a Mutating Method
變異方法能夠給隱含屬性self
一個全新的實例岖是,下面看代碼帮毁。
struct Point {
var x = 0.0
var y = 0.0
mutating func movePoint(deltaX : Double, deltaY : Double) {
self = Point(x: x + deltaX, y: y + deltaY)
}
}
上面是結(jié)構(gòu)體,其實對于枚舉類型一樣豺撑,變異方法可以把self
設(shè)置為相同枚舉類型中的不同成員烈疚。
下面看一下代碼。
enum TriStateSwitch {
case Off, Low, High
mutating func next(){
switch self {
case .Off:
self = .Low
case .Low:
self = .High
case .High:
self = .Off
}
}
}
class JJSwiftVC: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
var light = TriStateSwitch.Low
print(light)
light.next()
print(light)
light.next()
print(light)
}
}
下面看一下輸出結(jié)果
Low
High
Off
類型方法
??它相當(dāng)于OC
中的類方法前硫,在swift
中叫做類型方法胞得。聲明類的類型方法是要在func
關(guān)鍵字之前加上關(guān)鍵字class
,聲明結(jié)構(gòu)體和枚舉的類型方法,在方法的func
關(guān)鍵字之前加上關(guān)鍵字static
阶剑。也即是說你可以在swift
中不僅為類定義類型方法跃巡,還可以為結(jié)構(gòu)體和枚舉定義類型方法。
類型方法都是按照如下方式進行調(diào)用牧愁。
class SomeClass{
class func someTypeMethod(){
//type method implementation goes here
}
}
someClass.someTypeMethod()
??一個類型方法可以調(diào)用本類中另外一個類型方法的名稱素邪,而無需在方法名稱前面加上類型名稱的前綴,同樣結(jié)構(gòu)體和枚舉的類型方法也能夠直接通過靜態(tài)屬性的名稱訪問靜態(tài)屬性猪半,而不需要類型名稱前綴兔朦。
struct LevelTracker {
static var highestUnlockLevel = 1
static func unlockLevel(level : Int){
if level > highestUnlockLevel {
highestUnlockLevel = level
}
}
static func levelIsUnlocked(level : Int) -> Bool{
return level <= highestUnlockLevel
}
var currentLevel = 1
mutating func advanceToLevel(level : Int) -> Bool {
if LevelTracker.levelIsUnlocked(level: level){
currentLevel = level
return true
}
else {
return false
}
}
}
LevelTracker
監(jiān)測玩家已解鎖的最高等級,這個值被存儲在靜態(tài)屬性highestUnlockLevel
中磨确,LevelTracker
還定義了兩個類型方法unlockLevel
和levelIsUnlocked
沽甥,方法unlockLevel
:一旦新等級被解鎖,就會更新highestUnlockLevel
的值乏奥,方法levelIsUnlocked
:如果某個給定的等級已經(jīng)解鎖就會返回true
摆舟。同時,currentLevel
用于監(jiān)測玩家當(dāng)前等級邓了,定義了advanceToLevel
實例方法進行管理恨诱,這個方法會在更新currentLevel
之前判斷請求的等級是否已經(jīng)解鎖,返回的是一個Bool
值骗炉。
下面我們看玩家類使用LevelTracker
監(jiān)測和更新每一個玩家的發(fā)展進度照宝。
class Player {
var tracker = LevelTracker()
let playerName : String
func completedLevel(level : Int) {
LevelTracker.unlockLevel(level: level + 1)
tracker.advanceToLevel(level: level + 1)
}
init(name: String) {
playerName = name
}
}
Player
類創(chuàng)建了一個LevelTracker
實例tracker
來監(jiān)測這個用戶的等級進度,提供了方法completedLevel
:一旦玩家完成某個指定等級就調(diào)用它句葵,這個方法為所有玩家解鎖下一級厕鹃,并更新當(dāng)前進度為下一等級。
下面我們看全部完整代碼笼呆。
struct LevelTracker {
static var highestUnlockLevel = 1
static func unlockLevel(level : Int){
if level > highestUnlockLevel {
highestUnlockLevel = level
}
}
static func levelIsUnlocked(level : Int) -> Bool{
return level <= highestUnlockLevel
}
var currentLevel = 1
mutating func advanceToLevel(level : Int) -> Bool {
if LevelTracker.levelIsUnlocked(level: level){
currentLevel = level
return true
}
else {
return false
}
}
}
class JJSwiftVC: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
var player = Player(name : "John")
player.completedLevel(level: 1)
print("highest level is unlocked is \(LevelTracker.highestUnlockLevel)")
}
}
class Player {
var tracker = LevelTracker()
let playerName : String
func completedLevel(level : Int) {
LevelTracker.unlockLevel(level: level + 1)
tracker.advanceToLevel(level: level + 1)
}
init(name: String) {
playerName = name
}
}
下面看輸出結(jié)果
highest level is unlocked is 2
現(xiàn)在可以看見未解鎖的等級到了2了熊响。
后記
未完旨别,待續(xù)~~~