斯坦福CS193P 2017-2018 第4節課筆記
阿新 • • 發佈:2018-12-18
以下內容為swift4.0中的特性
Struct
- 值型別(記憶體分配在棧上,賦值或者函式的引數傳遞時通過拷貝來實現)
- Copy-on-write: 通過寫時複製的方式提升記憶體的使用效率。在值需要改變的時候才執行拷貝操作。
- Mutating: 使用mutating來標識需要使用copy-on-write特性
- 無法繼承
- 不可修改的struct使用let來宣告
Protocol
是一組方法的集合,不能儲存資料。可以protocol實現swift中的多重繼承
protocol優勢
1.使API更加靈活
2.通過delegate在View和Controller之間實現關聯和結構化通訊
3.強制行為,比如Dictionary的key必須遵循hashable協議
4.不同類實現相同的功能,比如String, Array可以執行集合型別的方法。
5.實現多重繼承
包含可選的方法protocol
- 通常情況下,protocol中定義的方法都是需要實現的。
- 如果有可以選擇實現的方法,需要在方法前使用optional來宣告,有可選方法的protocol需要使用@objc來標明。
- 如果一個類實現帶有可選方法的protocol,這個類一定是NSObject的子類
定義protocol
protocol SomeProtocol : InheritedProtocol1, InheritedProtocol2 { var someProperty: Int { get set } func aMethod(arg1: Double, anotherArgument: String) -> SomeType mutating func changeIt() init(arg: Type) }
- 任何實現了SomeProtocol的資料結構必須要實現InheritedProtocol1和InheritedProtocol2
- 如果protocol中定義了property,需要指明get和set方法實現哪個或者都需要實現
- 對於會修改receiver的方法,需要在方法前使用mutating關鍵字來修飾
- 如果限制某些protocol只能由class來實現,需要在protocol定義時新增class作為父類
protocol SomeProtocol : class, InheritedProtocol1, InheritedProtocol2 { var someProperty: Int { get set } func aMethod(arg1: Double, anotherArgument: String) -> SomeType mutating func changeIt() init(arg: Type) }
- protocol中也可以指明需要實現初始化方法
實現protocol
- class, enum, struct都可以實現protocol
class SomeClass : SuperclassOfSomeClass, SomeProtocol, AnotherProtocol {
// implementation of SomeClass here
// which must include all the properties and methods in SomeProtocol & AnotherProtocol
}
enum SomeEnum : SomeProtocol, AnotherProtocol {
// implementation of SomeEnum here
// which must include all the properties and methods in SomeProtocol & AnotherProtocol
}
struct SomeStruct : SomeProtocol, AnotherProtocol {
// implementation of SomeStruct here
// which must include all the properties and methods in SomeProtocol & AnotherProtocol
}
- class實現的protocol中包含init方法時,需要在init方法前新增required關鍵字,用於防止該類的子類在繼承時忘記實現該方法。
class SomeClass : SuperclassOfSomeClass, SomeProtocol, AnotherProtocol {
// implementation of SomeClass here, including ...
required init(...)
}
- class,struct和enum可以通過extension來實現protocol
extension Something : SomeProtocol {
// implementation of SomeProtocol here
// no stored properties though
}
String
字元的集合。和Objc的NSStrinig不同,使用String.Index表示字元在字串中的索引。
String.Index使用舉例如下
let pizzaJoint = “café pesto”
let firstCharacterIndex = pizzaJoint.startIndex // of type String.Index
let fourthCharacterIndex = pizzaJoint.index(firstCharacterIndex, offsetBy: 3) let fourthCharacter = pizzaJoint[fourthCharacterIndex] // é
if let firstSpace = pizzaJoint.index(of: “ “) { // returns nil if “ ” not found let
secondWordIndex = pizzaJoint.index(firstSpace, offsetBy: 1)
let secondWord = pizzaJoint[secondWordIndex..<pizzaJoint.endIndex]
}
NSAttributedString
NSAttibutedString的建立和使用舉例
let attributes: [NSAttributedStringKey : Any] = [ // note: type cannot be inferred here
.strokeColor : UIColor.orange,
.strokeWidth : 5.0 // negative number here would mean fill (positive means outline)
]
let attribtext = NSAttributedString(string: “Flips: 0”, attributes: attributes)
flipCountLabel.attributedText = attribtext // UIButton has attributedTitle
函式型別
函式型別和其他資料型別一樣,用於定義變數。
函式宣告
func 函式名(行參列表) -> 返回值 {程式碼實現}
閉包
閉包通常作為函式的引數
閉包使用舉例
let primes = [2.0, 3.0, 5.0, 7.0, 11.0]
let negativePrimes = primes.map({ -$0 }) // [-2.0, -3.0, -5.0, -7.0, -11.0]
let invertedPrimes = primes.map() { 1.0/$0 } // [0.5, 0.333, 0.2, etc.]
let primeStrings = primes.map { String($0) } // [“2.0”,”3.0”,”5.0”,”7.0”,”11.0”]
如果函式最後一個引數是閉包,可以將{}部分放到()的外面,如上面的語句3;如果函式只有一個閉包引數,可以將()省略,如上面的語句4。
閉包實現property的延時載入
var someProperty: Type = {
// construct the value of someProperty here
return <the constructed value>
}()