内存管理(上)

内存管理

  • 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)

图示引用计数.png

关于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

循环引用.png
避免循环引用:弱引用.png
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
避免循环引用:无主引用.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,688评论 1 330
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,559评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,749评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,581评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,741评论 3 271
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,684评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,122评论 2 292
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,847评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,441评论 0 228
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,939评论 2 232
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,333评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,783评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,275评论 3 220
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,830评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,444评论 0 180
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,553评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,618评论 2 249

推荐阅读更多精彩内容

  • 内存管理 简述OC中内存管理机制。与retain配对使用的方法是dealloc还是release,为什么?需要与a...
    丶逐渐阅读 1,857评论 1 16
  • 29.理解引用计数 Objective-C语言使用引用计数来管理内存,也就是说,每个对象都有个可以递增或递减的计数...
    Code_Ninja阅读 1,412评论 1 3
  • 一.开篇之初 内存管理解决的问题就是:1)防止野指针的生成(野指针:指向变量的指针还存在,但是所指向的内存已经被释...
    半纸渊阅读 960评论 0 1
  • iOS开发中, 之前一直使用swift, 因此对于Objective-C的内存管理机制长期处于混乱的一知半解状态....
    icetime17阅读 796评论 1 8
  • 为什么进行内存管理? 由于移动设备的内存极其有限,所以每个APP所占的内存也是有限制的,当app所占用的内存较多时...
    天天想念阅读 849评论 1 7