內(nèi)存管理
- ARC是Swift默認的內(nèi)存管理機制跟束,其針對堆上的對象,由編譯器自動生成操作引用計數(shù)的指令(retain或release)來管理對象的引用計數(shù)增加或減少稻爬。程序員無法手工控制遇汞。
- 哪些類型的對象收ARC管理
- 類class
- 閉包closure
- 哪些對象不受ARC管理
- 基礎數(shù)值類型
- 結(jié)構(gòu)struct
- 枚舉enum
- 元組tuple
class FileStream{
init(){
print("open file...")
}
func process(){
print("process file...")
}
deinit{
print("close file...")
}
}
class MyClass1{
var stream:FileStream?
}
class MyClass2{
static var stream:FileStream?
}
var fs1:FileStream() // r(1)
var mc:MyClass1?
mc!.stream=fs1 // r(2)
MyClass2.stream=fs1 // r(3)
fs1?.process()
fs1=nil //r(2)
mc!.stream=nil //r(1)
Myclass2.stream=nil // r(0)
關于Auto Release
- Swift原生對象不支持autorelease消息粥航,也就沒有必要使用Autorelease Pool來管理內(nèi)存峰值。
- 如果Swift調(diào)用Objective-C函數(shù)返回autorelease對象祟身,那么如果出現(xiàn)內(nèi)存峰值過高的風險菩貌,仍然需要使用Autorelease Pool來管理司澎。
- Autorelease Pool在Swift中使用尾隨閉包形式實現(xiàn)。
import Foundation
class FileStream{
init(){
print("open file...")
}
func process(){
print("process file...")
}
deinit{
print("close file...")
}
}
func getStream()-> FileStream?{
var fs:FileStream?
fs=FileStream()
return fs;
}
func useNativeSwiftObject(){
for index in 0...10{
print("\(index) for start...")
var stream=getStream()
stream?.process()
stream=nil
print("\(index) for end...\n")
}
}
/*
func useObjecAutoreleaseObject(){
if let filepath = NSBundle.mainBundle().pathForResource("2015",ofType:"jpg"){
for _ in 0..<5{
autoreleasepool{
for _ in 0..<1000{
let data=NSdata.dataWithContentsOfMappedFile(filepath)
}
}
}
}
}
*/
print("\n......invoke......\n")
useNativeSwiftObject()
print("......continue......")
循環(huán)引用于內(nèi)存泄露
對象間的循環(huán)引用會造成ARC引用計數(shù)無法釋放被引用的任何一個對象栋豫,從而造成內(nèi)存泄露挤安。
解決循環(huán)引用造成的內(nèi)存泄露有三種方式:
1.在合適的地方,手動將循環(huán)引用解除丧鸯。
2.如果允許對象引用為nil蛤铜,可將引用聲明為弱引用(weak)
3.如果不允許對象引用為nil,可將對象聲明為無主引用(unowned)弱引用在對象被釋放后丛肢,ARC會將引用設置為nil围肥。無主引用在對象被釋放后,ARC不會設置nil蜂怎,訪問時會拋運行時錯誤(空懸指針)穆刻。
class Computer{
var name: String
var display: Monitor?
init(name:String){
self.name=name
print("Computer init")
}
deinit{
print("Computer deinit")
}
}
class Monitor{
var no: Int
weak var device: Computer?
init(no:Int){
self.no=no
print("Monitor init")
}
deinit{
print("Monitor deinit")
}
}
var imac:Computer?
var screen:Monitor?
imac=Computer(name:"Jason's iMac")
screen=Monitor(no:29)
imac!.display=screen
screen!.device=imac
//imac!.display=nil
imac=nil
screen=nil
import Foundation
class Car{
var name:String
var engine:Engine?
init(name:String){
self.name=name
print("Car init")
}
deinit{
print("Car deinit")
}
}
class Engine{
var no:Int
unowned var car : Car
init(no:Int,car : Car){
self.no=no
self.car=car
print("Engine init")
}
deinit{
print("Engine deinit")
}
}
var bmw:Car?
var engine:Engine?
bmw=Car(name:"BMW")
engine=Engine(no:400,car:bmw!)
bmw!.engine=engine
bmw=nil
//engine=nil