泛型編程
泛型是一種參數(shù)化類型的機(jī)制(類型占位符),為算法和類型的實(shí)現(xiàn)提供了更高的復(fù)用性、更強(qiáng)的安全型、更好的性能。
泛型支持包括:函數(shù)、類、結(jié)構(gòu)、枚舉
類型參數(shù)的實(shí)例化:
“泛型類型的實(shí)例化”即用實(shí)際類型替換占位符。泛型類型參數(shù)實(shí)例化的過程可以采用自動(dòng)類型推斷。
Swift采用編譯時(shí)泛型模型,即在編譯時(shí)進(jìn)行泛型類型的實(shí)例化,產(chǎn)生新的類型碼或函數(shù)碼。
如果類型參數(shù)是值類型,泛型實(shí)例化會(huì)為不同的值類型生成不同的類型碼(尺寸不同)。
如果類型參數(shù)是引用類型,泛型實(shí)例化會(huì)為所有不同的引用類型生成同一份類型碼(基于同等尺寸的指針)。
協(xié)議的關(guān)聯(lián)類型:
通過typealias可以為protocol定義一到多個(gè)關(guān)聯(lián)類型。
在實(shí)現(xiàn)協(xié)議時(shí),可將關(guān)聯(lián)類型設(shè)置為泛型類型參數(shù)(或自動(dòng)類型推斷)。
協(xié)議的關(guān)聯(lián)類型可以看作是支持“泛型版的協(xié)議”。
泛型約束:
類型約束為泛型類型參數(shù)提供了更多的功能約定。
Swift 要求顯式的類型約束,編譯器在泛型類型參數(shù)實(shí)例化時(shí)會(huì)檢查約束的有效性。
泛型類型約束支持兩類約束:基類約束、協(xié)議約束。
Where子句約束:指定關(guān)聯(lián)類型必須符合某種協(xié)議、或者和其他關(guān)聯(lián)類型相等。
//泛型函數(shù)
func swapT<T>(inout a:T, inout b:T)
{
var tmp = a
a = b
b = tmp
}
var a:Double = 2.0
var b:Double = 3.0
swapT(&a, &b)
struct Student {
var no:Int
}
var sa = Student(no:100)
var sb = Student(no:101)
swapT(&sa, &sb)
//泛型類型
class Stack<T>{
var items = [T]()
func push(items:T){
items.append(item)
}
func pop() ->T{
return items.removeLast()
}
}
var stack1 = Stack<Int>()
stack1.push(10)
stack1.push(20)
stack1.push(30)
函數(shù)類型與閉包
函數(shù)類型:
定義:(參數(shù)類型1,參數(shù)類型2,...)->返回值類型
函數(shù)類型是一種引用類型,類似于函數(shù)指針??梢詫⒑瘮?shù)類型應(yīng)用于任何使用類型的地方:變量、參數(shù)、返回值。
函數(shù)類型實(shí)例化支持:全局函數(shù)、嵌套函數(shù)、成員函數(shù)(實(shí)例方法與靜態(tài)方法)
func addString(s1:String, sSex s2:String, sAge s3:String)->String{
return "Name is" + s1 + "and sex is" +s2+"and age is" + s3
}
var addSome:(String,String,String)->String = addString
let anotheraddSome = addString
閉包:
一對花括號“{}”包裹著的代碼塊就是一個(gè)閉包。
閉包表達(dá)式語法:
{ (parameters) -> returnType in
statements
}
閉包可以定義參數(shù)和返回值。
參數(shù):常量、變量、inout、可變參數(shù)、元組類型。
in關(guān)鍵字:表示閉包的參數(shù)和返回值類型定義已經(jīng)完成。
數(shù)組sort函數(shù)對字符串?dāng)?shù)組進(jìn)行排序:
let names = ["Lily", "Anna", "Duty", "Poly", "Gray"]
func compareName(s1:String, s2:String) -> Bool {
return s1 < s2
}
var sortedArray = names.sort(compareName)
sortedArray = names.sort({(s1:String,s2:String)->Bool in return s1 < s2})
用for in遍歷,打印元素值
var arrayValue = "array value:"
for index in sortedArray{
arrayValue += (index+",")
}
print(arrayValue)

簡化后的閉包表達(dá)式:
sortedArray = names.sort(>)
使用for in循環(huán),打印元素值
結(jié)果為:

trailing閉包
//聲明一個(gè)使用閉包作為參數(shù)的函數(shù)
fun someFunction(someBag:()->()){//函數(shù)體}
//不使用trailing
someFunction({
//閉包語句
//閉包語句
//閉包語句
})
//使用trailing
someFunction(){
//如果函數(shù)只有閉包表達(dá)式一個(gè)參數(shù),可以省略"()"
//閉包主體
}
類型擴(kuò)展
擴(kuò)展(extension)
擴(kuò)展是向一個(gè)已有的類、結(jié)構(gòu)體或枚舉類型添加新的功能。
extension String {
func reverseString() -> String {
//do something if necessary
}
}
Swift中擴(kuò)展可以:
(1)添加計(jì)算實(shí)例屬性(computed property)和計(jì)算類屬性
(2)定義實(shí)例方法和類方法
(3)提供新的構(gòu)造器
(4)定義下標(biāo)(subscript)
(5)定義和使用新的嵌套類型
(6)使一個(gè)遵守某個(gè)接口
擴(kuò)展語法(Extension syntax)
聲明擴(kuò)展的關(guān)鍵字extension
extension SomteType {
// add sth
}
可以擴(kuò)展類型時(shí)讓類型遵守協(xié)議:
extension SomteType : SomeProtocol, OtherProtocol {
// do sth if necessary
}
擴(kuò)展類型,添加計(jì)算屬性:
// 添加長度單位屬性
extension Double {
var km: Double {
return self * 1_000.0
}
var m: Double {
return self
}
var cm: Double {
return self / 100.0
}
var mm: Double {
return self / 1_000.0
}
var ft: Double {
return self / 3.28084
}
}
let oneInch = 25.4.mm
println("One inch is \(oneInch) meters")
let threeFeet = 3.ft
println("Three feet is \(threeFeet) meters")
let sum = 10.4.km + 122.5.km
內(nèi)存管理
Swift中的ARC內(nèi)存管理是對引用類型的管理,即對類所創(chuàng)建的對象采用ARC管理。而對于值類型,如整型、浮點(diǎn)型、布爾型、字符串、元組、集合、枚舉和結(jié)構(gòu)體等,是由處理器自動(dòng)管理的,程序員不需要管理它們的內(nèi)存。
一、引用計(jì)數(shù)
每個(gè)Swift類創(chuàng)建的對象都有一個(gè)內(nèi)部計(jì)數(shù)器,這個(gè)計(jì)數(shù)器跟蹤對象的引用次數(shù),稱為引用計(jì)數(shù)(Reference Count,簡稱RC)。當(dāng)對象被創(chuàng)建的時(shí)候,引用計(jì)數(shù)為1,每次對象被引用的時(shí)候會(huì)使其引用計(jì)數(shù)加1,如果不需要的時(shí)候,對象引用斷開(賦值為nil),其引用計(jì)數(shù)減1。當(dāng)對象的引用計(jì)數(shù)為0的時(shí)候,對象的內(nèi)存才被釋放。
二、自動(dòng)引用計(jì)數(shù)
舉例:
class Employee {
var no : Int
var name : String
var job : String
var salary : Double
init(no : Int, name: String, job : String, salary : Double) {
self.no = no
self.name = name
self.job = job
self.salary = salary
print("員工\(name) 已經(jīng)構(gòu)造成功。")
}
deinit {
print("員工\(name) 已經(jīng)析構(gòu)成功。")
}
}
var ref1: Employee?
var ref2: Employee?
var ref3: Employee?
ref1 = Employee(no: 0001, name: "john", job :"Salesman", salary : 6600)
ref2 = ref1
ref3 = ref1
ref1 = nil
ref2 = nil
ref3 = nil
輸出結(jié)果:

