美文网首页
内存管理题

内存管理题

作者: 一个半吊子工程师 | 来源:发表于2020-10-30 17:20 被阅读0次

1.管理原则

1.1内存管理-黄金法则

The basic rule to apply is everything that increases the reference counter with alloc, [mutable]copy[withZone:] or retain is in charge of the corresponding [auto]release.

如果对一个对象使用了alloc、[mutable]copy、retain,那么你必须使用相应的release或者autorelease。

1.2类型定义:

基本类型:任何C的类型,如:int、short、char、long、struct、enum、union等属于基本类型或者结构体;

内存管理对于C语言基本类型无效;

任何继承与NSObject类的对象都属于OC类型。

所有OC对象都有一个计数器,保留着当前被引用的数量。

1.3内存管理对象:

OC的对象:凡是继承于NSObject;

每一个对象都有一个retainCount计数器。表示当前的被应用的计数。如果计数为0,那么就真正的释放这个对象。

alloc、retain、release函数:

1)alloc 函数是创建对象使用,创建完成后计数器为1;只用1次。

2)retain是对一个对象的计数器+1;可以调用多次。

3)release是对一个对象计数器-1;减到0对象就会从内存中释放。

增加对象计数器的三种方式:

1)当明确使用alloc方法来分配对象;

2)当明确使用copy[WithZone:]或者mutableCopy[WithZone:]copy对象的时;

3)当明确使用retain消息。

上述三种方法使得计数器增加,那么就需要使用[auto]release来明确释放对象,也就是递减计数器。

2. 非ARC模式,MRR(manual retain-release)

MRR内存管理里的一个核心原则,“只负责你拥有的对象的生命周期”,也就是说,如果你对一个对象有所有权,那么你就要负责其回收的工作,否则,你不需要,也不能取回收你不拥有的对象。

1:所有使用alloc, new, copy或mutabelCopy,以及这些关键词开头的函数返回的对象,你都是拥有所有权的,也就是要负责这些对象的内存回收工作。这是iOS开发中的一种约定,所以,当你编写自己的alloc, new或copy类型的函数时,也请遵循这样的命名规范。

2:retain返回的对象,拥有所有权。例如显示调用retain函数返回的结果,或者synthesize 的retain类型的成员变量。

3:所有使用其他函数返回的对象,没有所有权。

4:返回的对象的引用,没有所有权。

5:autorelease返回的对象没有所有权。

2.1 cocoa中的内存管理机制——引用计数

  • 引用计数(reference counting)又称为保留计数(retain counting),引用计数的数值表示有几个其它对象在使用它。
  • 每一个对象都拥有一个引用计数
  • 当对象被创建的时候,引用计数的值为1 当发送retain消息的时候,该对象的引用计数加1,该对象的引用计数为2
  • 当这个对象发送release消息的时候,该对象的引用计数减1
  • 当一个对象的引用计数为0时,系统自动调用dealloc方法,销毁该对象。

引用计数是实例对象的内存回收唯一参考
引用计数(retainCount)是Objective-C管理对象引用的唯一依据。调用实例的release方法后,此属性减一,减到为零时对象的dealloc方法被自动调用,进行内存回收操作,也就是说我们永不该手动调用对象的dealloc方法。
关于dealloc方法它的作用是,当对象的引用计数为0时,系统会自动调用dealloc方法,回收内存,它的一般写法为:


-(void)dealloc
{      
      [super  dealloc];
      [person release];                                                                                 
}        

在这里为什么要调用父类的dealloc方法呢?

  • 子类的某些实例是继承自父类的,因此,我们需要调用父类的dealloc方法,来释放父类拥有的这些对象。
    一般来说调用的顺序是,当子类的对象释放完时,然后再释放父类的所拥有的实例,这一点与调用初始化方法,正好相反。

2.2 对象所有权

当一个所有者(可以是任何一个OC对象)做了以下某个动作的时候,它就拥有了对一个对象的所有权。

  • 1,在OC中,对象不断的被其它创建、使用和销毁,为了保证程序不产生额外的内存开销,当对象不再被需要以后,应当被立即销毁。

  • 2,拥有对一个对象的使用权,我们称为是”拥有”这个对象。对象的拥有者个数至少为1,对象才得以存在,否则它应当被立即销毁。

  • 3,为了确定你(一个对象)何时具有对另外一个对象的所有权,以及明确对象所有者的权利和义务,Cocoa设立了一套标准。只有当你对一个对象做了alloc,copy和retain等操作之后,你才拥有它的所有权。当你不再需要这个对象的时候,你应该释放你对它的所有权。千万不要对你没有所有权的对象进行释放。

//(1)如果创建或者复制某个对象时,则拥有了该对象的所有权,即包含下列关键词时:
alloc,allocWithZone:,copy,copyWithZone:,mutableCopy,mutableCopyWithZone:

//(2)如果没有创建或复制对象,而是保留引用,同样拥有该对象的使用权
 retain
//(3)当拥有了某个对象的所有权,在不需要某一个对象时,需要释放他们,用
 release,autoRelease

2.3 自动释放池的相关用法

1)cocoa中的自动释放池(Autorelease pool),是能够自动释放赤忠的对象的。NSObject类提供了一个autorelease消息,当我们想一个对象发送autorelease消息的时候,这个对象就会随着释放池的销毁而释放。如果要向使用使用自动释放池释放对象,我们首先要有一个入池操作:

 //入池对象5.0之后的写法
//创建自动释放池
@autoreleasepool {
    //入池对象5.0之后的写法
 }

//入池对象5.0之前写法
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
[pool release];

自动释放池是以栈的形式实现的,当某个对象调用了autorelease方法时,该对象会被加入自动释放池的栈顶。对于发送了autorelease消息的对象,当自动释放池销毁时,自动释放池会对这些对象发送一条release消息,来释放他们。

2)向自动释放池发送release及drain消息的区别
当我们向自动释放池pool发送release消息时,它会向池中的每一个发送了autorelease消息的对象发送一条release消息,并且自身也会销毁。当向它发送drain消息时,只会释放里面吧的对象,而不会销毁自己。

3. ARC模式

当你在编译程序的时候提供自动管理内存的功能,它会自动加入内存的控制代码,控制对象的生命周期,大大简化了内存管理的步骤,ARC管理内容的原理就是,编译器会在适当的地方自动插入retain、release和autorelease消息

3.1 ARC机制下有几个明显的标志:

  • 不允许调用对象的 release方法
  • 不允许调用 autorelease方法
  • 再重写父类的dealloc方法时,不能再调用 [super dealloc];

3.2 ARC的注意点和优点

  • ARC的注意点

    • ARC是编译器特性,而不是运行时特性
    • ARC不是其它语言中的垃圾回收, 有着本质区别
  • ARC的优点

    • 完全消除了手动管理内存的烦琐, 让程序猿更加专注于app的业务
    • 基本上能够避免内存泄露
    • 有时还能更加快速,因为编译器还可以执行某些优化

3.3 ARC的判断原则

  • ARC的判断原则

    • 只要还有一个强指针变量指向对象,对象就会保持在内存中
  • 强指针

    • 默认所有指针变量都是强指针
    • 被__strong修饰的指针
 Person *p1 = [[Person alloc] init];
 __strong  Person *p2 = [[Person alloc] init];

  • 弱指针
    • 被__weak修饰的指针
__weak  Person *p = [[Person alloc] init];

  • 注意:当使用ARC的时候,暂时忘记“引用计数器”,因为判断标准变了。

相关文章

  • 内存管理题

    1.管理原则 1.1内存管理-黄金法则 The basic rule to apply is everything...

  • 面试题

    一。送分题 1.冒泡排序 二。拓展题 1.内存管理 侧重点是mrc下的内存管理机制 MRC,即Manua...

  • 喝着黑咖啡做操作系统期末考试试卷

    鸡肋,鸡肋,食之无味弃之可惜。 目录 考点提示 填空题 判断题 文件管理 用户接口 设备管理 进程管理 内存管理 ...

  • 新年过后献上关于Android内存泄漏的种种总结

    Android 内存泄漏总结 内存管理的目的就是让我们在开发中怎么有效的避免我们的应用出现内存泄漏的问 题。内存泄...

  • iOS 内存管理强化题

    MRC 下,如何设计一个方法,可以把传入的对象完全销毁? 附测试用例:

  • iOS内存管理详解

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

  • 作业

    一、选择题:(20 分,每题2 分) 1、下列哪个不属于内核的功能? ( A ) A 用户管理B 内存管理C 进程...

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

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

  • 操作系统之内存管理

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

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

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

网友评论

      本文标题:内存管理题

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