Swift2学习笔记(3)

前端之家收集整理的这篇文章主要介绍了Swift2学习笔记(3)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

初始化(Initialization)

  • 存储属性必须有初值。可以在声明时赋缺省值,也可以在构造器赋初值。
    存储属性为可选值时,其缺省值为nil。
    赋初值时属性观测器不会被调用
  • 构造器(Initializers)语法形式为 init(外部名1 内部名1: 类型1,外部名2 内部名2: 类型2 ...)
    缺省形式为 init(外部名1兼内部名1: 类型1,外部名2兼内部名2: 类型2 ...)
    即构造器的所有参数缺省外部名与内部名相同,要省略外部名需要把外部名设置为下划线。
    缺省形式 完整形式 最简形式
    调用 class Person{
    init(ea: Int,eb: Int){
    ea ...
    eb ...
    }
    }
    class Person{
    init(ea la: Int,eb lb: Int){
    la ...
    lb ...
    }
    }
    class Person{
    init(_ la: Int,_ lb: Int){
    la ...
    lb ...
    }
    }
    调用 Person(ea: 1,eb: 2) Person(ea: 1,eb: 2) Person(1,2)
  • 缺省构造器(Default Initializers):对于所有成员属性都具有缺省值的类和结构,编译器可以为其自动生成所有成员属性均被赋予缺省值的缺省构造器。
    成员逐一构造器(Memberwise Initializers):对于结构,编译器可以为其自动生成所有成员属性均被逐一赋值的成员逐一构造器。
    缺省构造器和成员逐一构造器的生成条件是类和结构没有用户自定义的构造器。
  • 构造器委托(Initializer Delegation):构造器之间的相互调用被称为构造器委托。
  • 类所具有的构造器可分为两种。
    指定构造器(Designated Initializers):具有必要性的基本构造器。每个类必须具有至少一个指定构造器。指定构造器必须初始化类的所有成员。指定构造器必须向上委托,即必须调用直接基类的指定构造器。没有用户自定义的指定构造器的类将会继承基类的所有指定构造器。
    便利构造器(Convenience Initializers):处于从属地位的辅助性构造器,通过关键字 convenience 指定。便利构造器必须横向委托,即必须调用所在类的其他构造器。便利构造器横向委托的终点必须是所在类的指定构造器。继承了或实现了基类的所有指定构造器的类将会继承基类的所有便利构造器。
  • 重写基类的构造器使用 override 关键字。
// 构造器参数的外部名和内部名
struct Celsius {
    var temperatureInCelsius: Double
    init(fromFahrenheit fahrenheit: Double) {
        // ..
    }
    init(kelvin: Double) {
        // ..
    }
    init(_ celsius: Double) {
        // ..
    }
}
let boilingPointOfWater = Celsius(fromFahrenheit: 212.0)
let freezingPointOfWater = Celsius(kelvin: 273.15)
let bodyTemperature = Celsius(37.0)
// 缺省构造器
class ShoppingListItem {
    var name: String?
    var quantity = 1
    var purchased = false
}
var item = ShoppingListItem()
// 成员逐一构造器
struct Size {
    var width = 0.0,height = 0.0
}
let twoByTwo = Size(width: 2.0,height: 2.0)

自动引用计数(ARCAutomatic Reference Counting)

  • 语言中没有垃圾回收器,采用自动引用计数来管理内存:对于同一个实例,创建时引用计数为0,多一次引用则引用计数自动加1,少一次引用则引用计数自动减1,引用计数为0时该实例自动被释放。
    class Person {}
    let p1 = Person() // 引用计数为1
    let p2 = p1 // 引用计数为2
    p2 = nil // 引用计数为1
    p1 = nil // 引用计数为0,实例被释放
    
  • 引用计数会带来循环引用(cyclic references)问题:A实例内部包含一个指向B实例的引用,而B实例内部也包含一个指向A实例的引用。由于A实例和B实例引用计数都不为0,两者均无法释放。
  • 为了解决循环引用问题,语言中引入弱引用(weak references)和非占有引用(unowned references),常规引用被称为强引用(strong references)。
    强引用:参与引用计数的常规引用。
    弱引用:不参与引用计数,生命周期中可指向空值的观察者引用。
    非占有引用:不参与引用计数,生命周期中不应该指向空值的观察者引用。
    所谓不参与引用计数,是说对于一个实例,即便多一次或者少一次弱引用或非占有引用,该实例的引用计数也不会发生变化,即弱引用或非占有引用不影响引用计数器对于实例的释放。
    强引用 弱引用 非占有引用
    关键字 weak unowned
    是否参与引用计数
    let还是var let,var var let
    是否optional 是(?!),否 是(?)
  • 经典使用场景:
    强引用 弱引用 非占有引用
    人和房间问题 class Person {
    var apartment: Apartment?
    }
    class Apartment {
    weak var tenant: Person?
    }
    顾客和信用卡问题 class Customer {
    var card: CreditCard?
    }
    class CreditCard {
    unowned let customer: Customer
    }
    国家和首都问题 class Country {
    var capitalCity: City!
    }
    class City {
    unowned let country: Country
    }

泛型(Generics)

  • 泛型函数(Generic Functions)
    func swapTwoValues<T>(inout a: T,inout _ b: T) {
        let temp = a
        a = b
        b = temp
    }
    
  • 泛型类型(Generic Types)
    struct Stack<Element> {
        var items = [Element]()
        mutating func push(item: Element) {
            items.append(item)
        }
        mutating func pop() -> Element {
            return items.removeLast()
        }
    }
    

猜你在找的Swift相关文章