头像制作网站营销策划方案ppt模板
一个朴实无华的目录
- 今日学习内容:
- 1.Swift 可选链
- 1.1定义
- 1.2通过可选链调用方法
- 1.3使用可选链调用下标脚本
- 1.4通过可选链接调用来访问下标
- 1.4访问可选类型的下标
- 2.Swift 自动引用计数(ARC)
- 2.1实例之间的循环强引用会造成内存泄露
- 2.2弱引用(weak)和无主引用(unowned)实例
- 2.3闭包引起的循环强引用
- 2.4 当闭包和捕获的实例总是互相引用时并且总是同时销毁时,将闭包内的捕获定义为无主引用。
今日学习内容:
1.Swift 可选链
1.1定义
如果目标有值,调用就会成功,返回该值
如果目标为nil,调用将返回nil
class Person {var residence: Residence?
}class Residence {var numberOfRooms = 1
}let john = Person()// 链接可选residence?属性,如果residence存在则取回numberOfRooms的值
if let roomCount = john.residence?.numberOfRooms {print("John 的房间号为 \(roomCount)。")
} else {print("不能查看房间号")
}
以上程序执行输出结果为:不能查看房间号
只要是通过可选链的请求就意味着最后numberOfRooms总是返回一个Int?而不是Int。
1.2通过可选链调用方法
使用可选链的来调用可选值的方法并检查方法调用是否成功
class Person {var residence: Residence?
}// 定义了一个变量 rooms,它被初始化为一个Room[]类型的空数组
class Residence {var rooms = [Room]()var numberOfRooms: Int {return rooms.count}subscript(i: Int) -> Room {return rooms[i]}func printNumberOfRooms() {print("房间号为 \(numberOfRooms)")}var address: Address?
}// Room 定义一个name属性和一个设定room名的初始化器
class Room {let name: Stringinit(name: String) { self.name = name }
}// 模型中的最终类叫做Address
class Address {var buildingName: String?var buildingNumber: String?var street: String?func buildingIdentifier() -> String? {if (buildingName != nil) {return buildingName} else if (buildingNumber != nil) {return buildingNumber} else {return nil}}
}let john = Person()if ((john.residence?.printNumberOfRooms()) != nil) {print("输出房间号")
} else {print("无法输出房间号")
}
以上程序执行输出结果为:无法输出房间号
1.3使用可选链调用下标脚本
实例中创建一个 Residence 实例给 john.residence,且在他的 rooms 数组中有一个或多个 Room 实例,那么你可以使用可选链通过 Residence 下标脚本来获取在 rooms 数组中的实例了:
let john = Person()
let johnsHouse = Residence()
johnsHouse.rooms.append(Room(name: "客厅"))
johnsHouse.rooms.append(Room(name: "厨房"))
john.residence = johnsHouselet johnsAddress = Address()
johnsAddress.buildingName = "The Larches"
johnsAddress.street = "Laurel Street"
john.residence!.address = johnsAddressif let johnsStreet = john.residence?.address?.street {print("John 所在的街道是 \(johnsStreet)。")
} else {print("无法检索到地址。 ")
}以上程序执行输出结果为:John 所在的街道是 Laurel Street。
1.4通过可选链接调用来访问下标
let john = Person()let johnsHouse = Residence()
johnsHouse.rooms.append(Room(name: "客厅"))
johnsHouse.rooms.append(Room(name: "厨房"))
john.residence = johnsHouseif let firstRoomName = john.residence?[0].name {print("第一个房间名为\(firstRoomName)")
} else {print("无法检索到房间")
}
以上程序执行输出结果为:第一个房间名为客厅
1.4访问可选类型的下标
var testScores = ["Dave": [86, 82, 84], "Bev": [79, 94, 81]]
testScores["Dave"]?[0] = 91
testScores["Bev"]?[0]++
testScores["Brian"]?[0] = 72
// the "Dave" array is now [91, 82, 84] and the "Bev" array is now [80, 94, 81]
2.Swift 自动引用计数(ARC)
2.1实例之间的循环强引用会造成内存泄露
class Person {let name: Stringinit(name: String) { self.name = name }var apartment: Apartment?deinit { print("\(name) 被析构") }
}class Apartment {let number: Intinit(number: Int) { self.number = number }var tenant: Person?deinit { print("Apartment #\(number) 被析构") }
}// 两个变量都被初始化为nil
var runoob: Person?
var number73: Apartment?// 赋值
runoob = Person(name: "Runoob")
number73 = Apartment(number: 73)// 意感叹号是用来展开和访问可选变量 runoob 和 number73 中的实例
// 循环强引用被创建
runoob!.apartment = number73
number73!.tenant = runoob// 断开 runoob 和 number73 变量所持有的强引用时,引用计数并不会降为 0,实例也不会被 ARC 销毁
// 注意,当你把这两个变量设为nil时,没有任何一个析构函数被调用。
// 强引用循环阻止了Person和Apartment类实例的销毁,并在你的应用程序中造成了内存泄漏
runoob = nil
number73 = nil
2.2弱引用(weak)和无主引用(unowned)实例
class Module {let name: Stringinit(name: String) { self.name = name }var sub: SubModule?deinit { print("\(name) 主模块") }
}class SubModule {let number: Intinit(number: Int) { self.number = number }weak var topic: Module?deinit { print("子模块 topic 数为 \(number)") }
}var toc: Module?
var list: SubModule?
toc = Module(name: "ARC")
list = SubModule(number: 4)
toc!.sub = list
list!.topic = toctoc = nil
list = nil
class Student {let name: Stringvar section: Marks?init(name: String) {self.name = name}deinit { print("\(name)") }
}
class Marks {let marks: Intunowned let stname: Studentinit(marks: Int, stname: Student) {self.marks = marksself.stname = stname}deinit { print("学生的分数为 \(marks)") }
}var module: Student?
module = Student(name: "ARC")
module!.section = Marks(marks: 98, stname: module!)
module = nil
2.3闭包引起的循环强引用
class HTMLElement {let name: Stringlet text: String?lazy var asHTML: () -> String = {if let text = self.text {return "<\(self.name)>\(text)</\(self.name)>"} else {return "<\(self.name) />"}}init(name: String, text: String? = nil) {self.name = nameself.text = text}deinit {print("\(name) is being deinitialized")}}// 创建实例并打印信息
var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
print(paragraph!.asHTML())
2.4 当闭包和捕获的实例总是互相引用时并且总是同时销毁时,将闭包内的捕获定义为无主引用。
class HTMLElement {let name: Stringlet text: String?lazy var asHTML: () -> String = {[unowned self] inif let text = self.text {return "<\(self.name)>\(text)</\(self.name)>"} else {return "<\(self.name) />"}}init(name: String, text: String? = nil) {self.name = nameself.text = text}deinit {print("\(name) 被析构")}}//创建并打印HTMLElement实例
var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world")
print(paragraph!.asHTML())// HTMLElement实例将会被销毁,并能看到它的析构函数打印出的消息
paragraph = nil
以上程序执行输出结果为:<p>hello, world</p>
p 被析构