内存管理
- ARC是Swift默认的内存管理机制,其针对堆上的对象,由编译器自动生成操作引用计数的指令(retain或release)来管理对象的引用计数增加或减少。程序员无法手工控制。
- 哪些类型的对象收ARC管理
- 类class
- 闭包closure
- 哪些对象不受ARC管理
- 基础数值类型
- 结构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来管理内存峰值。
- 如果Swift调用Objective-C函数返回autorelease对象,那么如果出现内存峰值过高的风险,仍然需要使用Autorelease Pool来管理。
- Autorelease Pool在Swift中使用尾随闭包形式实现。
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......")
循环引用于内存泄露
-
对象间的循环引用会造成ARC引用计数无法释放被引用的任何一个对象,从而造成内存泄露。
-
解决循环引用造成的内存泄露有三种方式:
1.在合适的地方,手动将循环引用解除。
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

网友评论