2016年1月15日 星期五

swift 2.0 備忘錄

//結構是value類型, 類別是reference類型
所以struct用let宣告之後,裡面的property都不可以再賦值。
String是struct NSString是class

//集合類型(Collection Types)
swift中的Array Dictionary Set資料結構都是值類型,在objective C中都是reference類型。

//檢查API是否可用(#available)
if #available(iOS 9, OSX 10.10, *) {
     //之後的API
} else {
    //其他的
}

//lazy先宣告而不初始化,等到第一次使用時再初始化。

//property observer: willSet & didSet
在初始化時不會被呼叫,被始化化之後才會發生效用。

//靜態property
你可以用static關鍵字加在var之前,就可以宣告靜態的property給所有動態物件共用。

//struct一但宣告出來就不能改動,如果要用func改property值,要加上mutating關鍵字
mutating func changeValue() { ... }

//下標(Subscript)
用subscript關鍵字來宣告下標,下標就是array[0]後面用中刮號的部份
你可用不同類型的參數宣告多組下標,就叫「下標多載」。

//class變成單純的基礎class,不像Objective-C中強制一定要繼承自NSObject。

//防止覆寫(Override)或繼承(Inheritance)
使用final關鍵字
你可以加在你的fun property subscript,那subclass就無法override;
如果你加在class上,那這個class就無法被繼承。

//當你初始化物件時,實際上就是去call類別的init()方法,如果你沒有實作init(),那swift會幫你呼叫一個預設的。

//外部參數名稱(External Parameter Names)
假設你在Test類別中宣告func changeValue(value y: Int) {x = y}方法
則你在呼叫的時候會看到:test.changeValue(value: 1)
其中value就是外部參數名稱
        y就是區域(Local)參數名稱

//指定建構器(designated initializer)與 便利建構器(convenience initializer)
指定建構器:init(params)
便利建構器:convenience init(params)
其中
init一定要呼叫到superclass的init。(rootClass不用)
convenience init可以呼叫其他的convenience init但最後一定要呼叫到init

//容錯建構器(Failable Initializer)
init?()會在無法正確初始化後,回傳nil給你。

//必要建構器(Required Initializer)
required init是用來表示你有某個init是在subclass實作init時,不可被忽略的。
如果你的subclass有修動或新增init,那required init是必需被實作的。

//解構器deinit {}
一個物件被Swift釋放之前,會先呼叫解構器deinit。deinit只被使用在class上。
當物件被設為nil的時候,會由subclass deinit 往superclass deinit的順序執行。

//weak reference/ unowned reference
如果兩個物件互相用stroong reference的property指著對方,就會產生reference cycle而造成memory leak,為了解決這個問題,swift提出兩種解法:
weak reference是用在optional的物件上,當一方被指為nil時,ARC機制會自動幫你把weak ref的物件指向nil,因此原物件會正常被釋放,程式也不會crash。
unowned ref是用在nonoptional的物件上,這種物件是你已知不會變nil的,所以當一方被釋放掉,memory不會leak,但你如果仍使用這個unowned reference,ARC不會幫你設為nil,蘋果文件上說保證你會crash,所以要自行避免這種情況。

//Type Casting for Any and AnyObject
swift提供兩個特殊的實體型態
AnyObject: 可以代表任意Class的實體
Any: 可以代表任何實體,例如func、Struct、Enum、Class。

//巢狀型態(Nested Types)
swift允許在Type當中再定義另一個Type,意思是說你可以在Class、struct、enum中再定義別的
Class、Struct、Enum。
用點運算來讀取,例如:Car.Door.Window.rawValue

//擴充(Extension)的作用就像是Objective-C中的類目(Category)
你只能幫原類別新增convenience init建構器,不能新增init
你可以新增實體方法與類別方法,但不能override原有方法。

//Protocol等於告訴型別說:你一定要實作ooxx東西!

//Class-Only Protocol
你可以限定你的Protocol只能讓Class使用,Struct跟Enum都不可以使用。
protocol ClassOnlyProtocal: class {
    //define protocol here
}

//Protocol Composition
用來指定多個protocol所組成的合成protocol
protocol <Protocol1, Protocol2>

//泛型(Generic)
用<>宣告,中間可以放任何名稱來當作"預留類型",一般慣用T,所以你會看到<T>來表示T是等下要用來換成你想到的類型。
struct Queue<T> {
    var items = [T]()

    mutating func enqueue(item: T) {
        items.append(item)
    }

    mutating func dequeue() -> T {
        return items.removeAtIndex(0)
    }
}

//Access Control
swift中只有三種Access Control
Public: 可以跨模組存取。
Internal: 為預設值,只可供模組內部的任意成員存取。
Private: 只能在該.swift中的成員存取,模組內部的其他file中的成員皆不可存取。

//不同進制的表示法
//二進制0b
let binaryInt = 0b1001
//八進制0o
let octalInt = 0o21
//十進制
let decimalInt = 17
//十六進制0x
let hexadecimalInt = 0x11

//位元運算子(Bitwise Operator)
NOT: ~
AND: &
OR: |
XOR: ^
左移(left shift): << 右移(right shift): >>

//運算如果發生溢位會出錯,但可以在運算子前加上&,來忽略溢位的部份,例如n = n &+ 1。

//運算子重載(Operator Overloading)
不同於C或Objective-C,C++或swift都可以做Operator Overloading,也就是你可以把+ - * / 做成你自己想要的功能。(但指派運算子(=)跟三元條件運算子(a ? b : c)不適用於Operator Overlading)。

//不只是可以重載既有的運算子,你也可以自定自己的運算子(Custom Operator)
prefix func ∑ {}
infix func + {}
postfix func π {}

//Error Handling
do {
    try 呼叫函式A
} catch 錯誤類型 {
    // 錯誤處理
}

func A(id: String) throw {
    guard var _ = id else {
        throw YourErrorType.errorN
    }
}

enum YourErrorType: ErrorType {
    case errorN
    case errorG(errorMsg: String)
}

沒有留言:

張貼留言