Standford 2015 iOS讀書會 week2: 1. Applying MVC 2. More Swift and Foundation Frameworks
Transcript of Standford 2015 iOS讀書會 week2: 1. Applying MVC 2. More Swift and Foundation Frameworks
enum
enum Op { case Operand(Double) case UnaryOperation(String, Double->Double) case BinaryOperation(String, (Double, Double)->Double) }
enum也能定義init
initializer
init() { knownOps["×"] = Op.BinaryOperation("×", {$0*$1} ) }
init() { knownOps["×"] = Op.BinaryOperation("×"){$0*$1} }
case BinaryOperation(String, (Double, Double)->Double)
initializer
init() { knownOps["×"] = Op.BinaryOperation("×"){$0*$1} knownOps["÷"] = Op.BinaryOperation("÷"){$1/$0} knownOps["+"] = Op.BinaryOperation("+"){$0+$1} knownOps["−"] = Op.BinaryOperation("−"){$1-$0} knownOps["√"] = Op.UnaryOperation("√"){sqrt($0)}
}
case BinaryOperation(String, (Double, Double)->Double)
initializer
init() { knownOps["×"] = Op.BinaryOperation("×", *) knownOps["÷"] = Op.BinaryOperation("÷"){$1/$0} knownOps["+"] = Op.BinaryOperation("+", +) knownOps["−"] = Op.BinaryOperation("−"){$1-$0} knownOps["√"] = Op.UnaryOperation("√", sqrt)
}
case BinaryOperation(String, (Double, Double)->Double)
operator也是function
權限管理員 access control
internal,public,private可作⽤用於class、struct、enum、property、 method、initializer、subscript、protocol、variable、constant、function
private func evaluate(ops:[Op]) -> (result:Double?, remainingOps:[Op]) { if !ops.isEmpty { var remainingOps = ops let op = remainingOps.removeLast() switch op { case .Operand(let operand): return (operand, remainingOps) case .UnaryOperation(_, let operation): let operandEvaluation = evaluate(remainingOps) if let operand = operandEvaluation.result { return (operation(operand), operandEvaluation.remainingOps) } case .BinaryOperation(_, let operation): let op1Evaluation = evaluate(remainingOps) if let operand1 = op1Evaluation.result { let op2Evaluation = evaluate(op1Evaluation.remainingOps) if let operand2 = op2Evaluation.result { return (operation(operand1, operand2), op2Evaluation.remainingOps) } } } } return (nil, ops) } func evaluate() -> Double? { let (result, _) = evaluate(opStack) return result }
recursion
列印enum private enum Op:Printable { case Operand(Double) case UnaryOperation(String, Double->Double) case BinaryOperation(String, (Double, Double)->Double) var description:String { get { switch self { case .Operand(let operand): return "\(operand)" case .UnaryOperation(let symbol, _ ): return symbol case .BinaryOperation(let symbol, _): return symbol } } } }
遵從Printable protocol和定義description property
init() { func learnOp(op:Op) { knownOps[op.description] = op } learnOp(Op.BinaryOperation("×", *)) learnOp(Op.BinaryOperation("÷"){$1/$0}) learnOp(Op.BinaryOperation("+", +)) learnOp(Op.BinaryOperation("−"){$1-$0}) learnOp(Op.UnaryOperation("√", sqrt)) }
init() { knownOps["×"] = Op.BinaryOperation("×", *) knownOps["÷"] = Op.BinaryOperation("÷"){$1/$0} knownOps["+"] = Op.BinaryOperation("+", +) knownOps["−"] = Op.BinaryOperation("−"){$1-$0} knownOps["√"] = Op.UnaryOperation("√", sqrt)
}
optional is enumenum Optional<T> { case None case Some(T) }
var x:String? = nil x = Optional<String>.None x = "hello" x = Optional<String>.Some("hello")
var y = x!
switch x { case .Some(let value): y = value case .None: // raise an exception break }
playground的optional不再印出some
range搭配array
let array = ["a","b","c","d"] let subArray1 = array[2...3] let subArray2 = array[2..<3] println("\(subArray1[1]) \(subArray2[0])")
String.Index
extension String : CollectionType {
/// A character position in a `String` struct Index : BidirectionalIndexType, Comparable, Reflectable {
每個字佔據的記憶體⼤大⼩小不同
型別⽅方法和屬性
宣告時須同時設定初始值
以static宣告 型別⽅方法和屬性
class Baby { static var maxAge:Int = 100 static func cry(){ } }
Baby.cry() Baby.maxAge = 300
取消⾃自動產⽣生的 external name 利⽤用 _
⾃自動產⽣生的external name: 1. init的每個參數 2. ⽅方法裡的每個參數(第⼀一個參數除外,不包含function )
偵測屬性變更的 property observer
• 在property宣告裡定義willSet & didSet
• willSet將在屬性即將設定時被呼叫
• didSet將在屬性已設定時被呼叫
• 當初始化設定property時不會觸發
• 設定即觸發,即使設定⼀一樣的值
• 不適合let宣告的屬性
接受參數的彈性 initializer
init參數⾃自動產⽣生同名的external name利⽤用self區分age
不能再⽤用Baby()⽣生寶寶,因為沒有default initializer但可另外再定義無參數的init()
initializer的繼承
• 情況⼀一:若⼦子類別沒有定義任何 designated initializer,它將繼承⽗父類別的 designated initializer。
• 情況⼆二:如果滿⾜足情況⼀一,或⼦子類別覆寫了⽗父類別所有的 designated initializer,它 將繼承⽗父類別的 convenience initializer。
as!和forclass Baby { func cry() { } }
var babyArray:[AnyObject] = [Baby(), Baby()] for baby in babyArray as! [Baby] { baby.cry() }
注意: Any轉型會crash
struct Baby { func cry() { } }
var babyArray:[Any] = [Baby(), Baby()] for baby in babyArray as! [Baby] { baby.cry() }
assertion
release的版本不會crash,assert將被忽略,只有debug版會
func assert(condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = default, line: UWord = default)
1. @autoclosure2. 呼叫function時,有預設值的參數可省略
func validation() -> String? { return "Pass" }
assert(validation() != nil, "the validation function returned nil")
結果為false時,程式將crash