swift学习-构造,析构-(12/30)

上午忙着一个新项目上线的问题,中午吃饭也挺晚。吃完饭回来睡了一会,所以中午没有学swift。 下午从3点开始,看到5点,晚上又看了很久。
今天看了不少,到第173页。
swift引入的不确定类型(?),总觉得有点太过复杂,把原来许多挺好理解的东西都搞的四不像的。
还有类的构造过程,引入便利构造器,还有可失败构造器,以及一系列默认构造器,再配合以继承,真的太臃肿而繁琐。感觉下个版本,构造函数这里肯定要大改。
今天发现了一个官方做app的教程,看了一点,很不错,有swift的,xcode的,还有ui设计的,很容易让人快速进入app开发。挺不错的,看完swift就看这个教程吧。
笔记如下:

1 可失败构造器。如果一个类,结构体或者枚举,在构造自身的过程中有可能失败,则定义为一个可失败的构造器,语法为init?。
注: 可失败构造器的参数名和参数类型,不能与其他非可失败构造器的参数名及类型相同。
构造失败,返回nil。
例如:

struct Animal {
    let species: String

    init?(species: String?) {
        if ((species == nil)
            || (species!.isEmpty)){
            return nil
        } else {
            self.species = species!
        }
    }
}

//返回可选类型 Animal?
let animal = Animal.init(species: "")

带原始值的枚举类型会自带一个可失败构造器init?(rawValue:)。
2 你可以用子类的可失败构造器覆盖父类的可失败构造器,你也可以用子类的非可失败构造器覆盖一个基类的可失败构造器。
注:一个非可失败构造器永远也不能代理调用一个可失败构造器。你可以用一个非可失败构造器覆盖一个可失败构造器,反过来却不行。
在构造器前加required关键字来保证该类的所有子类都必须实现该构造器。当子类在覆盖父类的required构造器时,必须同样加required关键字,无需加override关键字。
3 使用闭包或全局函数初始化存储属性。

struct Checkerboard {
    let boardColors: [Bool] = {
        var temporaryBoard = [Bool]()
        var isBlack = false

        for i in 1...10 {
            for j in 1...10 {
                temporaryBoard.append(isBlack)
                isBlack = !isBlack
            }
        }

        return temporaryBoard
    }() //()很关键
}

var checkrboard = Checkerboard()

4 析构,swift的析构函数通过deinit定义。不允许主动调用自己的析构函数,
swift通过引用计数的方式来进行gc,所以触发deinit的方式,可以简单的将该引用设置为nil。

class Persion {
    var name: String

    init(name: String = "sigh") {
        self.name = name

        print("hi \(name)")
    }

    deinit {
        print("bye bye")
    }
}

var p1: Persion? = Persion()
var p2: Persion? = p1

p1 = nil
p2 = nil //触发析构

5 闭包循环引用。

class HtmlElement {
    let name: String
    let text: String?

    //在默认的闭包中可以使用self,因为只有在初始化完成,且self确实存在时,才能访问lazy属性
    lazy var asHtml: ()-> String = {
        var res: String

        if let text = self.text {
            res = "<\(self.name)>\(text)"
        } else {
            res = "<\(self.name)/>"
        }

        return res
    }

    init(name: String, text: String? = nil) {
        self.name = name
        self.text = text
    }
}

var htmlElement = HtmlElement(name: "hello")

print(htmlElement.asHtml())

在闭包中使用了self,强引用了类,而类也强引用了闭包。
swift对于循环引用的解决方案,引入弱引用和无主引用的方式,感觉也是有点偷懒的设计,完全可以在编译层面解决这个问题,而不是说把这些暴露给用户。

明天继续看吧。
这周目标200页,问题应该不大。

你可能感兴趣的:(swift学习-构造,析构-(12/30))