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初始化

類,結構和枚舉當 Swift 聲明後準備初始化類實例。初始值被初始化爲存儲屬性,並且新的實例的值也被進一步進行初始化。創建初始化函數的關鍵字是通過 init() 方法。Swift 初始化不同於 Objective-C,它不返回任何值。其作用是檢查新創建的實例的其處理前初始化。Swift 還提供了「反初始化」過程中執行的內存管理操作當實例被釋放。

對於存儲的屬性初始化器的作用

存儲的屬性處理實例之前初始化類和結構的實例。 存儲屬性使用初始分配和初始化值,從而消除了需要調用屬性觀察者。 初始化用於存儲屬性:

  • 創建初始值

  • 要在屬性定義中指定默認屬性值

  • 爲特定的數據類型,初始化實例 init()方法被使用,init()函數沒有傳遞參數。

語法

init() { //New Instance initialization goes here }

示例

struct rectangle { var length: Double var breadth: Double init() { length = 6 breadth = 12 } } var area = rectangle() println("area of rectangle is \(area.length*area.breadth)")

當我們使用 playground 運行上面的程序,得到以下結果。

area of rectangle is 72.0

這裏結構 'rectangle' 使用成員長寬高爲 「double」 的數據類型進行初始化。init()方法被用於爲新創建的成員的長度和初始化double 類型的數值。 計算長方形的面積,並通過調用矩形函數返回。

通過默認設置屬性值

Swift 語言提供 init()函數來初始化存儲的屬性值。此外,用戶必須規定默認在聲明類或結構的成員初始化屬性值。當屬性的值在整個程序中時一樣時,我們可以在聲明部分單獨聲明它,而不是在 init()中初始化。默認情況下,用戶設置屬性值時能夠繼承被定義爲類或結構。

struct rectangle { var length = 6 var breadth = 12 } var area = rectangle() println("area of rectangle is \(area.length*area.breadth)")

當我們使用 playground 運行上面的程序,得到以下結果。

area of rectangle is 72.0

在這裏,代替聲明長和寬在 init()中,在聲明本身時就初始化值了。

參數初始化

在 Swfit 語言用戶提供以初始化參數初始化,使用定義作爲 init()的一部分。

struct Rectangle { var length: Double var breadth: Double var area: Double init(fromLength length: Double, fromBreadth breadth: Double) { self.length = length self.breadth = breadth
area = length * breadth } init(fromLeng leng: Double, fromBread bread: Double) { self.length = leng self.breadth = bread
area = leng * bread } } let ar = Rectangle(fromLength: 6, fromBreadth: 12) println("area is: \(ar.area)") let are = Rectangle(fromLeng: 36, fromBread: 12) println("area is: \(are.area)")

當我們使用 playground 運行上面的程序,得到以下結果。

area is: 72.0
area is: 432.0

局部及外部參數

初始化參數具有類似於的函數和方法參數局部和全局參數名稱。局部參數聲明用於初始化體,外部參數聲明訪問用於調用初始化。Swift 函數初始化和方法不同,它們不識別哪些初始化用於該函數調用。

爲了克服這個問題,Swift 引入了一個自動外部名稱爲 init()的每個參數。 這種自動外部名稱是等同的每一個初始化參數局部名字之前寫入。

struct Days { let sunday, monday, tuesday: Int init(sunday: Int, monday: Int, tuesday: Int) { self.sunday = sunday self.monday = monday self.tuesday = tuesday } init(daysofaweek: Int) { sunday = daysofaweek
monday = daysofaweek
tuesday = daysofaweek } } let week = Days(sunday: 1, monday: 2, tuesday: 3) println("Days of a Week is: \(week.sunday)") println("Days of a Week is: \(week.monday)") println("Days of a Week is: \(week.tuesday)") let weekdays = Days(daysofaweek: 4) println("Days of a Week is: \(weekdays.sunday)") println("Days of a Week is: \(weekdays.monday)") println("Days of a Week is: \(weekdays.tuesday)")

當我們使用 playground 運行上面的程序,得到以下結果。

Days of a Week is: 1
Days of a Week is: 2
Days of a Week is: 3
Days of a Week is: 4
Days of a Week is: 4
Days of a Week is: 4

不帶外部名稱參數

當外部名稱不需要一個初始化下劃線「_」,這是用來覆蓋默認行爲。

struct Rectangle { var length: Double init(frombreadth breadth: Double) { length = breadth * 10 } init(frombre bre: Double) { length = bre * 30 } init(_ area: Double) { length = area } } let rectarea = Rectangle(180.0) println("area is: \(rectarea.length)") let rearea = Rectangle(370.0) println("area is: \(rearea.length)") let recarea = Rectangle(110.0) println("area is: \(recarea.length)")

當我們使用 playground 運行上面的程序,得到以下結果。

area is: 180.0
area is: 370.0
area is: 110.0

可選屬性類型

當一些實例存儲的屬性不返回任何值該屬性使用 「optional」 類型,表示「沒有值」則返回特定類型的聲明。當存儲的屬性被聲明爲「optional」,它會自動初始化值是'nil' 在其初始化過程中。

struct Rectangle { var length: Double? init(frombreadth breadth: Double) { length = breadth * 10 } init(frombre bre: Double) { length = bre * 30 } init(_ area: Double) { length = area } } let rectarea = Rectangle(180.0) println("area is: \(rectarea.length)") let rearea = Rectangle(370.0) println("area is: \(rearea.length)") let recarea = Rectangle(110.0) println("area is: \(recarea.length)")

當我們使用 playground 運行上面的程序,得到以下結果。

area is: Optional(180.0)
area is: Optional(370.0)
area is: Optional(110.0)

修改常量屬性在初始化時

初始化還允許用戶修改的常量屬性的值。在初始化期間,類屬性允許它的類的實例被超類修改,而不是由子類進行修改。考慮在之前的程序「長度」的例子,被聲明爲主類 「變量」。下面的程序變量 'length' 修改爲'常量'變量。

struct Rectangle { let length: Double? init(frombreadth breadth: Double) { length = breadth * 10 } init(frombre bre: Double) { length = bre * 30 } init(_ area: Double) { length = area } } let rectarea = Rectangle(180.0) println("area is: \(rectarea.length)") let rearea = Rectangle(370.0) println("area is: \(rearea.length)") let recarea = Rectangle(110.0) println("area is: \(recarea.length)")

當我們使用 playground 運行上面的程序,得到以下結果。

area is: Optional(180.0)
area is: Optional(370.0)
area is: Optional(110.0)

默認初始化器

默認初始化提供給基類或結構的所有聲明屬性的新實例默認值。

class defaultexample { var studname: String? var stmark = 98 var pass = true } var result = defaultexample() println("result is: \(result.studname)") println("result is: \(result.stmark)") println("result is: \(result.pass)")

當我們使用 playground 運行上面的程序,得到以下結果。

result is: nil
result is: 98
result is: true

上述程序中定義了類的名字爲 「defaultexample'。三個成員函數默認初始化爲「studname?」存儲值爲 'nil' , 「stmark」爲98和「pass」的布爾值 「true」。 同樣,在類中的成員的值可以處理的類成員類型前初始化爲默認值。

按成員初始化器結構類型

當不提供由用戶自定義的初始化,在Swift 結構類型將自動接收「成員逐一初始化」。它的主要功能是初始化新的結構實例逐一初始化的默認成員,然後在新的實例屬性逐一通過名字傳遞給成員初始化。

struct Rectangle { var length = 100.0, breadth = 200.0 } let area = Rectangle(length: 24.0, breadth: 32.0) println("Area of rectangle is: \(area.length)") println("Area of rectangle is: \(area.breadth)")

當我們使用 playground 運行上面的程序,得到以下結果。

Area of rectangle is: 24.0
Area of rectangle is: 32.0

結構由默認初始化爲「length」爲「100.0」和「breadth」爲「200.0」,初始化期間爲它們的成員函數。但長度和寬度的變量值在處理過程中覆蓋爲24.0和32.0。

初始化委託值類型

初始委託定義調用其它初始化函數初始化。它的主要功能是充當可重用性,以避免在多個初始化代碼重複。

struct Stmark { var mark1 = 0.0, mark2 = 0.0 } struct stdb { var m1 = 0.0, m2 = 0.0 } struct block { var average = stdb() var result = Stmark() init() {} init(average: stdb, result: Stmark) { self.average = average self.result = result } init(avg: stdb, result: Stmark) { let tot = avg.m1 - (result.mark1 / 2) let tot1 = avg.m2 - (result.mark2 / 2) self.init(average: stdb(m1: tot, m2: tot1), result: result) } } let set1 = block() println("student result is: \(set1.average.m1, set1.average.m2) \(set1.result.mark1, set1.result.mark2)") let set2 = block(average: stdb(m1: 2.0, m2: 2.0), result: Stmark(mark1: 5.0, mark2: 5.0)) println("student result is: \(set2.average.m1, set2.average.m2) \(set2.result.mark1, set2.result.mark2)") let set3 = block(avg: stdb(m1: 4.0, m2: 4.0), result: Stmark(mark1: 3.0, mark2: 3.0)) println("student result is: \(set3.average.m1, set3.average.m2) \(set3.result.mark1, set3.result.mark2)")

當我們使用 playground 運行上面的程序,得到以下結果。

(0.0,0.0) (0.0,0.0)
(2.0,2.0) 5.0,5.0)
(2.5,2.5) (3.0,3.0)

初始化函數委派規則

值類型

類類型

不支持像結構和枚舉值類型繼承。參照其他初始化函數通過 self.init 完成

支持繼承。檢查所有存儲的屬性值初始化

類繼承和初始化

類類型有兩種初始化函數,以檢查是否定義存儲屬性接收初始值,即指定初始化和方便初始化函數。

指定初始化和便捷初始化器

指定的初始化

便捷初始化器

作爲一個類主要的初始化

作爲支持一個類初始化

所有的類屬性初始化和適當的超類的初始化被要求進一步初始化

指定的初始化程序被調用,便捷初始化創建類的實例爲特定用例或輸入值類型

每個類至少有一個指定初始化定義

非必須在便捷初始化函數強制規定在類不需要初始化函數。

Init(parameters) { statements }

便捷 init(parameters) { statements }

程序指定初始化

class mainClass { var no1 : Int // local storage init(no1 : Int) { self.no1 = no1 // initialization } } class subClass : mainClass { var no2 : Int // new subclass storage init(no1 : Int, no2 : Int) { self.no2 = no2 // initialization super.init(no1:no1) // redirect to superclass } } let res = mainClass(no1: 10) let print = subClass(no1: 10, no2: 20) println("res is: \(res.no1)") println("res is: \(print.no1)") println("res is: \(print.no2)")

當我們使用 playground 運行上面的程序,得到以下結果。

res is: 10
res is: 10
res is: 20

程序便捷的初始化

class mainClass { var no1 : Int // local storage init(no1 : Int) { self.no1 = no1 // initialization } } class subClass : mainClass { var no2 : Int init(no1 : Int, no2 : Int) { self.no2 = no2 super.init(no1:no1) } // Requires only one parameter for convenient method override convenience init(no1: Int) { self.init(no1:no1, no2:0) } } let res = mainClass(no1: 20) let print = subClass(no1: 30, no2: 50) println("res is: \(res.no1)") println("res is: \(print.no1)") println("res is: \(print.no2)")

當我們使用 playground 運行上面的程序,得到以下結果。

res is: 20
res is: 30
res is: 50

初始化繼承和重寫

Swift 默認不允許其子類繼承其超類初始化函數爲成員類型。繼承適用於超類初始化只能在一定程度上,這將在自動初始化程序繼承進行討論。

當用戶需要具有在超類,子類中定義的初始化器,初始化函數必須由用戶作爲自定義實現來定義。 當重寫,必須在子類到超類的使用 「override」關鍵字來聲明。

class sides { var corners = 4 var description: String { return "\(corners) sides" } } let rectangle = sides() println("Rectangle: \(rectangle.description)") class pentagon: sides { override init() { super.init() corners = 5 } } let bicycle = pentagon() println("Pentagon: \(bicycle.description)")

當我們使用 playground 運行上面的程序,得到以下結果。

Rectangle: 4 sides
Pentagon: 5 sides

指定和便捷初始化在動作中

class Planet { var name: String init(name: String) { self.name = name } convenience init() { self.init(name: "[No Planets]") } } let plName = Planet(name: "Mercury") println("Planet name is: \(plName.name)") let noplName = Planet() println("No Planets like that: \(noplName.name)") class planets: Planet { var count: Int init(name: String, count: Int) { self.count = count super.init(name: name) } override convenience init(name: String) { self.init(name: name, count: 1) } }

當我們使用 playground 運行上面的程序,得到以下結果。

Planet name is: Mercury
No Planets like that: [No Planets]

Failable初始化器

用戶必須被通知當在定義一個類,結構或枚舉值的任何初始化失敗時。變量初始化有時會成爲一種失敗,由於:

  • 無效的參數值

  • 缺少所需的外部來源

  • 有條件阻止初始化成功

若要捕獲拋出的初始化方法例外,swift 處理產生一種靈活初始化稱爲「failable 初始化」通知,是留給被忽視在初始化結構,類或枚舉成員。關鍵字捕獲 failable 初始值設定 「init?」。此外,failable 和 非failable 初始化函數不能使用相同的參數類型和名稱來定義。

struct studrecord { let stname: String init?(stname: String) { if stname.isEmpty {return nil } self.stname = stname } } let stmark = studrecord(stname: "Swing") if let name = stmark { println("Student name is specified") } let blankname = studrecord(stname: "") if blankname == nil { println("Student name is left blank") }

當我們使用 playground 運行上面的程序,得到以下結果。

Student name is specified
Student name is left blank

Failable初始值設定爲枚舉

Swift 語言提供了靈活性,可以使用 Failable 初始化函數通知用戶,從初始化留下來枚舉成員值。

enum functions { case a, b, c, d
init?(funct: String) { switch funct { case "one": self = .a case "two": self = .b case "three": self = .c case "four": self = .d default: return nil } } } let result = functions(funct: "two") if result != nil { println("With In Block Two") } let badresult = functions(funct: "five") if badresult == nil { println("Block Does Not Exist") }

當我們使用 playground 運行上面的程序,得到以下結果。

With In Block Two
Block Does Not Exist

Failable初始化器類

當枚舉和結構聲明 failable 初始化提醒的初始化失敗,在實現中的任意情況。然而, failable 初始化在類中提醒後,才存儲屬性設置初始值。

class studrecord { let studname: String! init?(studname: String) { self.studname = studname if studname.isEmpty { return nil } } } if let stname = studrecord(studname: "Failable Initializers") { println("Module is \(stname.studname)") }

當我們使用 playground 運行上面的程序,得到以下結果。

Module is Failable Initializers

覆蓋一個Failable初始化器

這樣初始化用戶也有提供子類覆蓋超類的failable 初始化。超級類 failable 初始化也可以在子類非 failable 初始化覆蓋。

覆蓋一個 failable 超類初始化時,nonfailable 子類初始化子類的初始化器不能委派到超類初始化器。

一個nonfailable初始化不能委託給一個failable初始化。

下面給出的程序描述failable和非failable初始化函數。

class Planet { var name: String init(name: String) { self.name = name } convenience init() { self.init(name: "[No Planets]") } } let plName = Planet(name: "Mercury") println("Planet name is: \(plName.name)") let noplName = Planet() println("No Planets like that: \(noplName.name)") class planets: Planet { var count: Int init(name: String, count: Int) { self.count = count super.init(name: name) } override convenience init(name: String) { self.init(name: name, count: 1) } }

當我們使用 playground 運行上面的程序,得到以下結果。

Planet name is: Mercury
No Planets like that: [No Planets] 

init! Failable初始化器

Swift 提供 「init?」定義一個可選實例failable初始化。要定義特定類型的隱式解包可選的 'int! ' 被指定。

struct studrecord { let stname: String init!(stname: String) { if stname.isEmpty {return nil } self.stname = stname } } let stmark = studrecord(stname: "Swing") if let name = stmark { println("Student name is specified") } let blankname = studrecord(stname: "") if blankname == nil { println("Student name is left blank") }

當我們使用 playground 運行上面的程序,得到以下結果。

Student name is specified
Student name is left blank

必需的初始化

聲明並初始化每個子類,「required」關鍵字的需要在init()函數之前定義。

class classA { required init() { var a = 10 println(a) } } class classB: classA { required init() { var b = 30 println(b) } } let res = classA() let print = classB()

當我們使用 playground 運行上面的程序,得到以下結果。

10
30
10