1. 程式人生 > >斯坦福CS193P 2017-2018 第4節課筆記

斯坦福CS193P 2017-2018 第4節課筆記

以下內容為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>
}()