内存管理(1)

来源:互联网 发布:mac cue 分割 wav 编辑:程序博客网 时间:2024/05/17 09:30

1.【掌握】内存管理的基本概念及范围

1、内存管理的基本概念

  • 1、为什么要进行内存管理?

    • 不难发现,苹果手机与安卓手机比较起来,苹果手机尤为流畅,性能相比起来会好很多,这个与苹果手机内存管理是分不开的。
    • 在程序开发中,应该及时将不用的数据回收,合理分配和管理内存 ,以提高程序的运行效率。

    • 2、哪些行为会增加内存占用?

  • 创建1个OC对象
  • 定义1个变量
  • 调用1个函数或者方法

    • 分析下图有哪些对象?
    • 由于移动设备的内存极其有限,所以每个APP所占的内存也是有限制的,当APP使用的内存超过20M,系统会向该APP发送内存警告消息,收到此消息后,需要回收一些不需要再继续使用的内存空间,比如回收一些不再使用的对象和变量等,否则程序会崩溃。

2、OC内存管理的范围

  • 管理范围:
  • 管理任何继承NSObject的对象,对其他的基本数据类型无效。
  • 本质原因:是因为对象和其他数据类型在系统中的存储空间不一样,其他局部变量主要存放于栈中,而对象存储于堆中。当代码块结束时,这个代码块中涉及的所有局部变量会被回收,指向对象的指针也被回收,此时,对象已经没有指针指向,但依然存在于内存中,造成内存泄露。

2.【理解】内管管理的原理及分类

1、内存管理的原理

  • 理解内存管理的原理,要清楚两个概念:

    • 1)对象的所有权
    • 2)引用计数器
    • 1)对象的所有权
    • 任何对象都可能拥有一个或多个所有者。只要一个对象至少还拥有一个所有者,它就会继续存在。
    • 那么什么叫拥有者呢? 举一个例子来看:
    • 假设有一个办公室, 给大家办公,那么如果办公室里没有人, 也就是说没有人在使用这个办公室, 就可以将办公室的灯关掉。 如果有人, 才会开灯。如果只有一个人在,那么当这个人离开的时候, 就表示需要将等关掉。

      那么此时就说明这个人是这间办公室的所有者.
    • 同时, 一个对象允许有多个所有者, 就好比:
    • 劲舞团
      这里写图片描述
    • 这里有很多人,如果其中某个人退出,此房间是不会被回收的,因为还有其他人在使用该房间。

    • LOL组队
      这里写图片描述

    • Cocoa所有权策略
  • 任何自己创建的对象都归自己所有,可以使用名字以“alloc”或“new”开头或名字中包含“copy”的方法创建对象,可以使用retain来获得一个对象的所有权。

    • 2)对象的引用计数器
    • 每个OC对象都有自己的引用计数器,是一个整数表示对象被引用的次数(有多少个所有者),即现在有多少东西在使用这个对象。对象刚被创建时,默认计数器值为1,当计数器的值变为0时,则对象销毁。
    • 对象的结构:
    • 在每个OC对象内部,都专门有8个字节的存储空间来存储引用计数器。


* 3)引用计数器的作用
* 引用计数器是判断对象要不要回收的依据(存在一种例外:对象值为nil时,引用计数为0,但不回收空间)就是计数器是否为0,若不为0则存在。

* 4)对引用计数器的操作
* 想要管理对象占用的内存,就要学会操作引用计数器。

  • 引用计数器的常见操作

    • retain消息:使计数器 +1(该方法返回对象本身)
    • release消息:使计数器 -1(不代表释放对象)
    • retainCount:获得对象当前的应用计数器值,输出:%ld %lu
    • 注意:release不代表销毁对象,仅仅是引用计数器-1

    • 5)对象的销毁

  • 当1个对象的应用计数器为0时,那么它将被销毁,其占用的内存被系统回收。
  • 当对象被销毁时,系统会自动向对象发送一条dealloc消息。一般会重写dealloc方法,在这里释放相关的资源,dealloc就像是对象的“临终遗言”。
  • 一旦重写了dealloc方法,就必须调用[super dealloc],并且放在代码块的最后调用。
  • 注意:不能直接调用dealloc方法
  • 一旦对象被回收了,那么他所占用的存储空间就不再可用,坚持使用会导致程序崩溃(野指针错误)

    • 注意;
  • 1) 如果对象的计数器不为0,那么在整个程序运行过程,它占用的内存就不可能被回收(除 非整个程序已经退出 )
  • 2)任何一个对象,刚生下来的时候,引用计数器都为1。(对象一旦创建好,默认引用计数器就是1)当使用alloc、new或者copy创建一个对象时,对象的引用计数器默认就是1.

2、内存管理的分类

  • Objective-C提供了三种内存管理方式:

    • 1.MannulReference-Counting(MRC,手动管理,在开发iOS4.1之前的版本的项目时我们要自己负责使用引用计数来管理内存,比如要手动 retain、release、autorelease 等,而在其后 的版本可以使用 ARC,让系统自己管理内存。)
    • 2.automatic reference-counting(ARC,自动引用计数,iOS4.1之后推出的)
    • 3.garbage collection(垃圾回收)。iOS不支持垃圾回收;

    • ARC作为苹果新提供的技术,苹果推荐开发者使用ARC技术来管理内存;

    • 开发中如何使用:需要理解MRC,但实际使用时尽量用ARC。

    • MRC和ARC的区别:
      这里写图片描述

4.【理解】内存管理的原则

1、内存管理的原则

  • 1.原则

    • 只要还有人在使用某个对象,那么这个对象就不会被回收;
    • 只要你想使用这个对象,那么就应该让这个对象的引用计数器+1;
    • 当你不想使用这个对象时,应该让对象的引用计数器-1;
  • 2.谁创建,谁release

    • 1)如果你通过alloc,new,copy来创建了一个对象,那么你就必须调用release或者 autorelease方法.
    • 2)不是你创建的就不用你去负责
  • 3.谁retain,谁release

    • 只要你调用了retain,无论这个对象时如何生成的,你都要调用release
  • 4.总结

    • 有始有终,有加就应该有减。曾经让某个对象计数器加1,就应该让其在最后-1.

2、内存管理研究内容

  • 1.野指针(僵尸对象)
    • 僵尸对象: 已经被销毁的对象(不能再使用的对象).
    • 野指针:指向僵尸对象(不可用内存)的指针.
    • 空指针: 没有指向存储空间的指针(里面存的是nil, 也就是0)
  • 2.内存泄露
    • 如果在程序结束后,对象没有被释放,此时称为内存泄露。
 Student *s = [[Student alloc] init]; Student *s1 = [s retain];
  • 那么,问题来了,最后由谁释放?
  • 1> 由s释放
 Student *s = [[Student alloc] init]; Student *s1 = [s retain]; [s release]; [s release];
  • 2> 由s1释放

    Student *s = [[Student alloc] init];Student *s1 = [s retain];[s1 release];[s1 release];
  • 两种方式都可以释放内存。
  • 但是,如果没有一种统一的释放原则,那么就会造成代码的混乱,舍都可以释放, 好比一个公司所有的领导没有分工一样, 任何事儿, 任何一个领导都可以插一嘴,很显然这样就没法干了, 因此需要有一个规范去约束使用。

5.【掌握】单个对象内存管理(野指针)

单个对象的野指针问题

  • 思考:对象在堆区的空间已经释放了,还能再使用p吗?

    Person *p = [[Person alloc] init];[p release];// 因为P已经被释放,此时调用p的run方法,此时会报错。// 我们把p叫做野指针,把p指向的对象叫做僵尸对象。[p run];
  • 野指针错误:访问了一块坏的内存(已经被回收的,不可用的内存)。

  • 僵尸对象:所占内存已经被回收的对象,僵尸对象不能再被使用。(默认情况下xcode为了提高编码效率,不会时时检查僵尸对象,打开僵尸对象检测方法)

这里写图片描述
* 打开僵尸对象监测的方法
这里写图片描述
这里写图片描述
这里写图片描述
* 注意:
* 1> 空指针:没有指向任何东西的指针,给空指针发送消息不会报错.

  • 关于nil和Nil及NULL的区别:

    • 1.nil: A null pointer to an Objective-C object. ( #define nil ((id)0) )

      • nil 是一个对象值。
      • Person *p = [Person new];
      • p = nil;
    • 2.Nil: A null pointer to an Objective-C class.

      • 如:Class someClass = Nil;给类对象赋值
    • 3.NULL: A null pointer to anything else. ( #define NULL ((void *)0) )

      • NULL是一个通用指针(泛型指针)。
    • 4.NSNull: A class defines a singleton object used to represent null values in collection objects (which don’t allow nil values).

      • [NSNull null]: The singleton instance of NSNull。
      • [NSNull null]是一个对象,他用在不能使用nil的场合。
  • 2> 不能使用[p retain]让僵尸对象起死复生。

  • 这里写图片描述
  • 3> 野指针操作
    这里写图片描述
0 0
原创粉丝点击