标签:
//*********Swift语言的内存管理基础*************
//内存管理:针对的是实例的内存占用的管理(放在堆里面)
//实例:1,由class类型构建的实例 2.闭包对象
/*
内存管理技术:ARC:Automatic Reference Count
自动:由于语言本身帮我们管理内存,不需要我们手机去管理
比如在c中就调用dealloc()
引用:let p = Person() p就是对Person()这个对象的一个引用
计数: let p = Person() +1
let pp = p +2
*/
//class Person {
// var name: String
// init(name: String) {
// self.name = name
// }
// deinit {
// print("\(name)Person deinit")
// }
//}
//
//var p: Person? = Person(name: "陈鹤") //+1
////p = nil
//var pp = p //+2
////pp = nil
//p = nil //+1
//pp = nil //计数为0
/*
计数增加:一般是把一个对象不断的赋值给变量或属性等
计数减少:手动把变量的值赋值为nil或者让其引用一个新的对象。
或者函数执行完毕例子:testArc
*/
//func testArc() {
// let p = Person(name: "陈璇")
// print(p.name)
//}
//testArc()
//*********内存管理中循环引用的问题*******
//俗气一点说就现在有了ARC以后,学习内存管理主要是学习怎解决循环引用的问题
//循环引用的阐述
class Student {
var name: String
var teacher:Teacher?
init (name: String) {
self.name = name
}
deinit {
print("\(name)Student deinit")
}
}
class Teacher {
var name: String
weak var student: Student?
init(name: String) {
self.name = name
}
deinit {
print("\(name)Teacher deinit")
}
}
var s: Student? = Student(name: "陈鹤")
var t: Teacher? = Teacher(name: "陈军")
s?.teacher = t
t?.student = s
//s?.teacher = t
//t?.student = s
t = nil
s = nil
/*解析:上面的代码输出的结果为 /陈军Teacher deinit/
因为s?.teacher = nil,那他t的计数就为1,这时s的计数为2,因为t?.student = s. 所以t = nil 就回销毁t对象,再s = nil,则会销毁s对象,之前的的s计数之所以为2是因为t?.student = s,可是t = nil 之后t就销毁了,那么t?.student = s 计数就不会加1了,所以这时的s只有s: Student? = Student(name: "陈鹤"),所以s = nil,s就被销毁了。
空悬指针:指一个对象没有指向任何东西,比如,你得的前方有人,你指着她让她去给你打杯水,反之 你前面没人你指着前面让谁帮你去打杯水呢。
内存泄露:指一个对象不被调用,但是占用了内存空间,列如,一个杯子装满水,你不喝,但是也补倒掉,那么这个杯子里面的空间就浪费了。
图形绘制:用图形工具绘画出上面的例子
//循环引用的解决方法:1.weak(弱yinyong)2.unowned(非拥有)
//解决空悬指针的办法只有两种:一种是把其的值赋值为nil,一种是让其指向一个新对象(这个方法不可行,从程序的角度来说)
//在Swift中只有用!?声明的类成员才能赋值为nil
严格来说,就三种情况需要考虑
第一种情况:就是两边都是?
解决方法:同上
第二种情况,一边为可空类型,一边为非可空类型(unowned)
*/
class Student2 {
var name: String
var teacher:Teacher2?
init (name: String) {
self.name = name
}
deinit {
print("\(name)Student2 deinit")
}
}
class Teacher2 {
var name: String
unowned var student: Student2
init(name: String,stu: Student2) {
self.name = name
self.student = stu
}
deinit {
print("\(name)Teacher2 deinit")
}
}
var s2: Student2? = Student2(name: "chenhe")
var t2: Teacher2? = Teacher2(name: "chenjun", stu: s2!)
s2?.teacher = t2
t2?.student = s2!
s2 = nil
t2 = nil
//第三种情况:两边都是非可空类型
class Student3 {
var name: String
var teacher: Teacher3! //nil
init(name: String,teacherName: String) {
self.name = name//这行代码运行后name有值,然后teacher有nil,所以stu:self就可以用
self.teacher = Teacher3(name: teacherName, stu: self)
}
deinit {
print("\(name) student3 deinit")
}
}
class Teacher3 {
var name: String
// var banzhang: Student3 = Student3(name: "xuesheng", teacher: self)//不能用self,除非lazy
unowned var student: Student3
init(name: String,stu: Student3) {
self.name = name
self.student = stu
}
deinit {
print("\(name) teacher3 deinit")
}
}
var s3: Student3? = Student3(name: "张角", teacherName: "天书")
var t3: Teacher3? = Teacher3(name: "天书", stu: s3!)
//上述的代码里解决了这个问题,但是会创建三个对象
//s3 = nil
t3 = nil
s3 = nil
/*
//如果两个类中,其属性都是非可空类型,并且相互引用,那么会导致两个对象永远不能创建出来 例子:
class Student4 {
var name: String
var teacher:Teacher4
init (name: String,teaa: Teacher4) {
self.name = name
self.teacher = teaa
}
deinit {
print("\(name)Student4 deinit")
}
}
class Teacher4 {
var name: String
unowned var student: Student4
init(name: String,stu: Student4) {
self.name = name
self.student = stu
}
deinit {
print("\(name)Teacher4 deinit")
}
}
var s4 = Student4(name: "dada", teaa: t4)
var t4 = Teacher4(name: "sda", stu: s4)
*/
//循环引用在闭包中得体现
class ClosureClass {
var name = "asdf"
lazy var myClosure: Void -> Int = {
// [unowned self] () -> Int in 使用unowned或者weak weak是可选的需要在self后面加! self!
// [unowned this = self,unowned self] () -> Int in //取别名this代替self
[weak self] () -> Int in
print(self!.name)
return 10
}
deinit {
print("CloseureClass deinit")
}
}
//这里有两个对象 一个是ClosureClass 一个是闭包对象
var c: ClosureClass? = ClosureClass()
c?.myClosure()
c = nil
标签:
原文地址:http://www.cnblogs.com/osxchen/p/4975734.html