上午忙着一个新项目上线的问题,中午吃饭也挺晚。吃完饭回来睡了一会,所以中午没有学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)</\(self.name)>"
} 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页,问题应该不大。
网友评论