课程来源于:Swift编程基础
文章目录
41. 自动内存释放, 反初始化器
41.1 自动引用计数ARC工作机制
- 自动引用
class Test{
var name:String
init(name:String) {
self.name = name
}
}
var t1 = Test(name: "hello")
var t2 = t1
var t3 = t2
t3.name = "aaa"
print(t1.name)
aaa
- ARC工作机制
对象
没有一个引用就会自动销毁, 内存销毁.
41.2 强引用
var t1 = Test(name: "hello") //强引用
41.3 反初始化器
class Test{
var name:String
init(name:String) {
self.name = name
}
deinit {
print("销毁中... " + self.name)
}
}
var t1:Test? = Test(name: "hello")
var t2:Test? = t1
var t3:Test? = t2
t1 = nil
t2 = nil
t3 = nil
var t:Test? = Test(name: "world")
t = nil
销毁中... hello
销毁中... world
42. 循环引用, 弱引用weak
42.1 循环引用
class TestA {
var name:String
var ref:TestB? = nil
init(name:String) {
self.name = name
}
deinit {
print("销毁中ing: " + self.name)
}
}
class TestB {
var name:String
var ref2:TestA? = nil
init(name:String) {
self.name = name
}
deinit {
print("销毁中ing: " + self.name)
}
}
var testA:TestA? = TestA(name: "A")
var testB:TestB? = TestB(name: "B")
//循环引用
testA!.ref = testB
testB!.ref2 = testA
//先把类中的循环引用里面的销毁
testA!.ref = nil
testB!.ref2 = nil
//然后销毁直接引用
testA = nil
testB = nil
销毁中ing: A
销毁中ing: B
42.2 弱引用weak
class TestA {
var name:String
//弱引用
weak var ref:TestB? = nil
init(name:String) {
self.name = name
}
deinit {
print("销毁中ing: " + self.name)
}
}
class TestB {
var name:String
//弱引用
weak var ref2:TestA? = nil
init(name:String) {
self.name = name
}
deinit {
print("销毁中ing: " + self.name)
}
}
var testA:TestA? = TestA(name: "A")
var testB:TestB? = TestB(name: "B")
//循环引用
testA!.ref = testB
testB!.ref2 = testA
//然后销毁直接引用
testA = nil
testB = nil
销毁中ing: A
销毁中ing: B
43. 无主引用unowned
先置空1
, 然后置空2
, 因为TestB
没有引用了, 则自动把3
置空了,销毁TestB
最后才把TestA
销毁
class TestA {
var name:String
var ref:TestB? = nil
init(name:String) {
self.name = name
}
deinit {
print("销毁中ing: " + self.name)
}
}
class TestB {
var name:String
var ref2:TestA
init(name:String, ref2:TestA) {
self.ref2 = ref2
self.name = name
}
deinit {
print("销毁中ing: " + self.name)
}
}
var testA:TestA? = TestA(name: "A")
//循环引用
testA!.ref = TestB(name: "B", ref2:testA!)
testA!.ref = nil
//然后销毁直接引用
testA = nil
销毁中ing: B
销毁中ing: A
43.1 无主引用
直接置空1
, 则TestA
先被销毁, 然后TestB
再销毁.
class TestA {
var name:String
var ref:TestB? = nil
init(name:String) {
self.name = name
}
deinit {
print("销毁中ing: " + self.name)
}
}
class TestB {
var name:String
//无主引用, 这是有值的
unowned var ref2:TestA
init(name:String, ref2:TestA) {
self.ref2 = ref2
self.name = name
}
deinit {
print("销毁中ing: " + self.name)
}
}
var testA:TestA? = TestA(name: "A")
//循环引用
testA!.ref = TestB(name: "B", ref2:testA!)
//testA!.ref = nil
//然后销毁直接引用
testA = nil
销毁中ing: A
销毁中ing: B
44. 闭包循环引用, 定义捕获列表
class Test {
var name:String
// lazy var data:() -> Void = {() -> Void in
// // self引用了对象
// print("姓名: " + self.name)
// }
// 定义捕获列表
lazy var data:() -> Void = {[unowned self]() -> Void in
print("姓名: " + self.name)
}
init(name:String) {
self.name = name
}
deinit {
print("Test的实例被释放 - " + self.name)
}
}
var t:Test? = Test(name: "hello")
t!.data()
t = nil
姓名: hello
Test的实例被释放 - hello
45. 可选链展开
class Data {
var name:String
init(name:String) {
self.name = name
}
func play(){
print(self.name)
}
}
class Test {
var name:String
var data:Data? = nil
init(outname name:String, data:Data){
self.name = name
self.data = data
}
deinit {
print("Test的实例被释放 - " + self.name)
}
}
var t:Test? = Test(outname: "hello", data: Data(name: "world"))
t = nil
//可选链展开
(t?.data)?.play()
//会报错
//(t?.data)!.play()
Test的实例被释放 - hello
46. 尾随闭包
46.1 多个参数的尾随闭包
func play1(param1:String, param2:(String) -> Void){
param2(param1 + "Swift")
}
play1(param1: "hello ", param2: {(data:String) -> Void in
print(data)
})
// 上式简写
play1(param1: "hello ", param2: {(data) in
print(data)
})
//尾随闭包: 必须是在最后一个参数位置
play1(param1: "world ") { (data:String) -> Void in
print(data)
}
//上式简写
play1(param1: "world ") { (data) in
print(data)
}
hello Swift
hello Swift
world Swift
world Swift
46.2 一个函数参数的尾随闭包
func play2(param:(String) -> String){
var value = param("swift")
print("返回值: " + value)
}
play2(param: {(data:String) -> String in
return data + " - ios"
})
//尾随闭包
play2(){(data:String) -> String in
return data + " - ios"
}
//上式简写
play2 { (data) -> String in
return data + " - ios"
}
返回值: swift - ios
返回值: swift - ios
返回值: swift - ios
46.3 一个无参数无返回值函数参数的尾随闭包
func play3(param:() -> Void){
param()
}
play3 (param: {() -> Void in
print("play3")
})
play3(param: {
print("play3")
})
play3(){
print("play3")
}
play3 {
print("play3")
}
play3
play3
play3
play3
46.4 一个无参数有返回值函数参数的尾随闭包
func play4(param:() -> String){
var value = param()
print("value4: " + value)
}
play4(param: { () -> String in
return "hello world"
})
play4 (){ () -> String in
return "hello world"
}
play4 (){
return "hello world"
}
play4 { () -> String in
return "hello world"
}
play4 {
return "hello world"
}
value4: hello world
value4: hello world
value4: hello world
value4: hello world
value4: hello world
46.5 不是尾随闭包
尾随闭包满足的条件是: 函数参数是该函数的最后一个参数
func play5(param:(Int) -> Void, param2:(Int)){
param(param2 * 2)
}
play5(param: {(data:Int) -> Void in
print(data)
}, param2: 100)
play5(param: {(data) in
print(data)
}, param2: 100)
200
200
47 错误捕获和处理
捕获错误后直接用异常
处理
enum TestError:String, Error{
case error1 = "错误1"
case error2 = "错误2"
}
func play(param:Int) throws -> String{
if(param < 0){
throw TestError.error1
}else if(param >= 0 && param <= 10){
throw TestError.error1
}
print("执行正常")
return "hello world"
}
do {
var value = try play(param: 100)
print(value)
}
catch TestError.error1 {
print(TestError.error1.rawValue)
}
catch TestError.error2 {
print(TestError.error2.rawValue)
}
defer {
print("defer")
}
执行正常
hello world
defer
捕获错误后用可选类型处理
enum TestError:String, Error{
case error1 = "错误1"
case error2 = "错误2"
}
func play(param:Int) throws -> String{
if(param < 0){
throw TestError.error1
}else if(param >= 0 && param <= 10){
throw TestError.error1
}
print("执行正常")
return "hello world"
}
var value = try? play(param: 100)
print(value != nil ? value! : "unknown")
print(value ?? "unknown")
if let p = value {
print(p)
}else{
print("unknown")
}
执行正常
hello world
hello world
hello world
只有确定时同一个枚举
错误时候可以用.
表示
func play2(param:TestError){
print("ssss")
}
play2(param: .error1)
ssss
48. 泛型类型限定, 协议关联类型
48.1 泛型的类型限定
class Data {
var name:String
init(name:String) {
self.name = name
}
}
//func play<T:Data>(param: T){
// print(param.name)
//}
//
//play(param: Data(name: "world"))
//需要向下类型转换
func play<T:Any>(param: T){
var a = param as! Data
print(a.name)
}
play(param: Data(name: "world"))
world
48.2 协议中的类型限定
protocol Test{
//限定类型
associatedtype D:Data
func play(param: D)
}
class Student: Test{
func play(param: Data) {
print(param.name)
}
}
var s = Student()
s.play(param: Data(name: "world"))
world
49. 访问权限简单说明
private
fileprivate
internal
public
open