您的位置:首页 > 移动开发 > Swift

Swift 基础学习(内存管理)

2016-03-12 14:25 501 查看
/*
Swift 内存管理
*/

/*
(1)析构方法
对象的内存被回收前夕被隐式调用的方法.主要执行一些额外的操
作.
比如: 关闭文件,断开网络,释放对象特有的一些资源等.
dealloc, MRC [obj release]
ARC, 弱化内存操作(Swift的析构方法,不用去管理内存).
*/
class FileHandle {
var fd: Int32? //文件描述符
init(path: String) {
let ret = open(path, O_RDONLY)
if (ret == -1) {
fd = nil
}else {
fd = ret
}
}
deinit {
if let ofd = fd {

close(ofd)
}
print("对象被销毁,持有资源被释放")
}
}
//对象 (引用类型)何时被销毁,对象没有任何引用的时候.
var ofh: FileHandle? = FileHandle(path: "/etc/passwd")
//目前没有任何的引用指向刚刚构造的对象.
//当注释掉,该对象没有被销毁,所以就不会走deinit析构方法
//ofh = nil

/*
(2)析构方法的自动继承-父类的析构方法会被自动调用,不需要
子类管理
*/
class SomeClass {
deinit {
print("SomeClass deinit!")
}
}
class SubOfClass: SomeClass {
deinit {
print("SubOfClass deinit!")
}
}
var osub: SubOfClass? = SubOfClass()
osub = nil

/*
(3)Swift语言的内存管理分析
*内存管理的对象-引用类型的对象(class类型)
*内存管理的原则:当没有任何引用指向某个对象的时候,系统会自
动销毁该对象.
*如何做到该原则:通过ARC技术
*/
class MenArc {
deinit {
print("deinit!")
}
}
var t0 = MenArc()
var t1 = t0
var t2 = MenArc()
//t0,t1跟t2指向同一个对象
t0 = t2
t1 = t2

/*
(4)weak引用(弱引用)
*/
class Ref {
deinit {
print("Ref deinit!")
}
func test() {
print("Test!")
}
}
//强引用,默认得引用方式
var strongRef = Ref()//引用计数为1
var strong1Ref1 = strongRef//引用计数为2
//弱引用,weak引用非常安全得引用方式.
weak var weakRef = Ref() //ARC
//当去掉weak修饰时,并不会调用deinit析构方法
// var weakRef = Ref() //ARC
//弱引用,是一个可选类型.

weak var weakRef1: Ref? = Ref()
//不能通过强制解析进行访问,编译会通过,运行会崩溃
//weakRef1!.test()
//当引用时,需要判断其是否为nil
if let wr = weakRef1 {
wr.test()
}

/*
(5)unowned引用(弱引用),不是可选类型
*/

/*
(6)循环强引用
ARC不是万能的,它可以很好的解决内存过早释放的问题,但是在
某些场合下不能很好的解决内存泄露的问题.
*/
class Person {
let name: String
init(name: String) {
self.name = name
}
var apartmet: Apartment?
deinit {
print("\(name) is being deinitialized")
}
}
class Apartment {
let number: Int
init(number: Int) {
self.number = number
}
weak var tenant: Person?
deinit {
print("Apartment #\(number) is being deinitialized")
}
}
var john: Person?
var number73: Apartment?
john = Person(name: "john Appleseed")
number73 = Apartment(number: 73)

john!.apartmet = number73
number73!.tenant = john

//两个对象没有被销毁,但是我们没有办法再访问它们了,内存泄露
//解决办法:将某一个属性设置为弱引用即可weak, 在var tenant前面添加关键字weak
john = nil
number73 = nil

/*
(7)unowned解决循环强引用
*/
class Customer {
let name: String
var card: CreditCard?
init(name: String) {
self.name = name
}
deinit {
print("\(name) is being deinitialized")
}
}
class CreditCard {
let number: UInt64
//解决循环引用
unowned let customer: Customer
init(number: UInt64, customer: Customer){
self.number = number
self.customer = customer
}
deinit{
print("Card #\(number) is being deinitalized")
}
}
var john1: Customer?
john1 = Customer(name: "John1 Appleseed")
john1!.card = CreditCard(number: 1245_5678_9012_3456, customer: john1!)
john1 = nil


(6)未用弱引用weak修饰前这4行代码对应以下图内容:
john = Person(name: "john Appleseed")
number73 = Apartment(number: 73)

john!.apartmet = number73
number73!.tenant = john




对应以下内容:
//导致内存泄露,john的apartment和number73的tenant两个对象还互相持有导致我们的内存泄露
john = nil
number73 = nil




通过将某个属性设置为弱引用weak时如图所示:
weak var tenant: Person?
john = Person(name: "john Appleseed")
number73 = Apartment(number: 73)

john!.apartmet = number73
number73!.tenant = john




对应以下图示:
john = nil
number73 = nil




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: