美文网首页
内存管理

内存管理

作者: 陌巷先森 | 来源:发表于2019-02-28 10:11 被阅读0次

一、管理对象

iOS中的对象一般有两种:

  • 引用类型:任何继承了NSObject类的对象
  • 值类型:比如int、char、float、double、struct、enum等基本数据类型

引用类型的对象都储存在系统的堆里面,一般由程序员分配释放,若程序员不释放,程序结束后由系统回收,分配方式类似于链表;非OC对象一般放在系统的栈里面,由操作系统自动分配释放,一般存放函数的参数值,局部变量的值等。

二、内存管理模型

内存管理模型有以下三种:

  • 自动垃圾收集(OS X)
  • 手工引用计数和自动释放池(MRC)
  • 自动引用计数(ARC)

三、引用计数(Reference Count)

苹果采用引用计数的方式来管理对象,当对象的引用计数为0后,表示对象没有被任何代码引用,此时对象将会被释放。

  • 当对象被创建(通过alloc、new或copy等方法)时,其引用计数初始值为1
  • 给对象发送retain消息,其引用计数加1
  • 给对象发送release消息,其引用计数减1
  • 当引用计数为0时,系统给对象发送dealloc消息,销毁对象

实例代码

Car *car = [[Car alloc] init];
NSLog(@"初始引用计数--%ld",car.retainCount);
[car retain];
NSLog(@"retain后引用计数--%ld",car.retainCount);
[car release];
NSLog(@"release后引用计数--%ld",car.retainCount);
[car release];
//当对象销毁后需要将指向对象的指针设为nil,避免产生野指针
car = nil;

打印如下:
HCCiOSDemo[1333:826830] 初始引用计数--1
HCCiOSDemo[1333:826830] retain后引用计数--2
HCCiOSDemo[1333:826830] release后引用计数--1
HCCiOSDemo[1333:826830] car对象被销毁了

三、MRC手动管理内存(Manual Reference Counting)

autorealease:将对象放入自动释放池中,当自动释放池销毁时会对自动释放池中的对象都进行一次realease操作,autorelease方法会返回对象本身,且调用完autorelease方法后,对象的计数不变。
自动释放池有两种创建方式

  • 使用NSAutoreleasePool创建
  • 使用@autoreleasepool创建

四、ARC自动管理内存(Automatic Reference Counting)

从OS X Lion和iOS 5开始,苹果引入了ARC机制,使用ARC后,系统会检测出何时需要保持对象,何时需要自动释放对象,编译器会管理好对象的内存,会在合适的地方插入retain,release和autorelease。
ARC提供四种修饰符,分别是__strong, __weak, __autoreleasing, __unsafe_unretained。

__strong

强引用,持有所指向对象的所有权,无修饰符情况下的默认值。

id __strong obj = [[NSObject alloc] init];
NSLog(@"obj引用计数--%@",[obj valueForKey:@"retainCount"]);
id __strong newObj = obj;
NSLog(@"obj引用计数--%@",[obj valueForKey:@"retainCount"]);
//将一个对象赋值给另外一个对象时,表示newObj的指针与obj的指针指向同一个NSObject对象,会将该对象的引用计数器加1

打印如下:
HCCiOSDemo[1753:1271122] obj引用计数--1
HCCiOSDemo[1753:1271122] obj引用计数--2

__weak

弱引用,不持有所指向对象的所有权,引用指向的对象内存被回收之后,引用本身会置nil,避免野指针。

id __weak obj1 = [[NSObject alloc] init];
NSLog(@"obj1引用计数--%@",[obj1 valueForKey:@"retainCount"]);
//__weak修饰的指针没有引起对象的引用计数器变化,因此在生成之后马上就会被释放
打印如下:
HCCiOSDemo[1831:1418225] obj1引用计数--(null)

__autoreleasing

自动释放对象的引用,一般用于传递参数

__unsafe_unretained

__unsafe_unretained作用需要和weak进行对比,它也不会引起对象的内部引用计数器的变化,但是,当其指向的对象被销毁时__unsafr_unretained修饰的指针不会置为nil。而且一般__unsafe_unretained就和它的名字一样是不安全,它不纳入ARC的内存管理

参考:完整项目资料下载

相关文章

  • iOS内存管理详解

    目录 block内存管理 autorelease内存管理 weak对象内存管理 NSString内存管理 new、...

  • 第10章 内存管理和文件操作

    1 内存管理 1.1 内存管理基础 标准内存管理函数堆管理函数虚拟内存管理函数内存映射文件函数 GlobalMem...

  • 操作系统之内存管理

    内存管理 包括内存管理和虚拟内存管理 内存管理包括内存管理概念、交换与覆盖、连续分配管理方式和非连续分配管理方式(...

  • JavaScript —— 内存管理及垃圾回收

    目录 JavaScript内存管理内存为什么需要管理?内存管理概念JavaScript中的内存管理JavaScri...

  • OC - OC的内存管理机制

    导读 一、为什么要进行内存管理 二、内存管理机制 三、内存管理原则 四、MRC手动内存管理 五、ARC自动内存管理...

  • 3. 内存管理

    内存管理 内存管理包含: 物理内存管理; 虚拟内存管理; 两者的映射 除了内存管理模块, 其他都使用虚拟地址(包括...

  • Go语言——内存管理

    Go语言——内存管理 参考: 图解 TCMalloc Golang 内存管理 Go 内存管理 问题 内存碎片:避免...

  • jvm 基础第一节: jvm数据区

    程序内存管理分为手动内存管理和自动内存管理, 而java属于自动内存管理,因此jvm的职能之一就是程序内存管理 j...

  • 内存管理

    内存管理的重要性。 不进行内存管理和错误的内存管理会造成以下问题。 内存泄露 悬挂指针 OC内存模型 内存管理是通...

  • 11-AutoreleasePool实现原理上

    我们都知道iOS的内存管理分为手动内存管理(MRC)和自动内存管理(ARC),但是不管是手动内存管理还是自动内存管...

网友评论

      本文标题:内存管理

      本文链接:https://www.haomeiwen.com/subject/oikirftx.html