Objective-c学习笔记03——内存管理


Objective-C可以开发apple家族系列产品的软件,这里记录成笔记方便日后复习:

一、内存管理概述

1 内存管理:内存管理是程序设计中常用的资源管理的一部分,每个计算机系统可供程序使用的资源都是有限的,这些资源包括内存、打开文件的数量以及网络连接等。
2 为什么要使用内存管理:当程序运行结束的时候,操作系统将回收其占用资源。但是,只要程序还在运行,它就会一直占用资源。如果不进行及时清理不用的资源,资源最终将被耗尽,程序将崩溃。每个程序都会使用内存,我们必须确保在需要的时候分配内存,而在程序运行结束时释放占用的内存。如果我们只分配而不是放内存,将发生内存泄漏:程序的内存占用不断增减,最终耗尽并导致程序崩溃。
注:不要使用刚释放的内存,否则我们将可能误用陈旧的数据,从而引起各种个样的问题。
3 所有权机制
1 > 只有当你对一个对象了alloc,copy或retain等操作以后,你才拥有它的所有权。
2 > 当你不需要这个对象时,你应当释放你对他的所有权。
3 > 你不可以对你没有所有权的对象执行释放操作。

由于IOS的内存管理机制不支持虚拟内存,所有在内存不足的情况下,不会去RAM上创建虚拟内存;所以一旦出现内存不足的情况,ios平台会通知所有已经运行的APP,不论是前台APP还是后台挂起的APP,都会收到 memory warningnotice 一旦APP收到 memory waringnotice 就应该回收占用内存较大的变量。

4 内存警报处理流程
1、APP收到系统发来的 memory waring 的 notice
2、APP释放占用较大的内存。
3、系统回收此APP所创建的atutorelease的对象。
4、APP返回到已经打开的页面时,系统重新调用 viewdidload 方法,view 重新加载页面数据,重新显示。

二、内存管理

1 自动垃圾收集

objective-c有垃圾回收,iOS运行环境并不支持垃圾收集,在这个平台开发程序时没有这方面的选择,只能用在Mac OS程序开发上,所以这里不做详细的解释。
如果要开发Mac OS程序,而且想要使用垃圾回收,需要在Xcode编译程序时打开如下选项:
(Build Setting) ——> Apple LLVM compiler 3.0 ——> Language中设置Objective-c Garbage Collection,改变其默认设置 Unsupported 为 Required,程序会使用动态垃圾收集重新构建。
垃圾收集发生在程序运行时,当系统检测到内存达低位时,就开始清理了,这是一个计算密集的过程:系统追踪所有的对象和引用,检测对象是否在使用(被引用),这就可能会引起应用的终端。这就是不推荐好似用内存收集特性的原因。

2 手工引用计数和自动释放池
手工管理内存的范围:任何继承了NSObject 的对象,并且使用了alloc、copy、mutableCopy和New为前缀的方法创建的对象都不会被自动释放,则需要进行手动管理。
引用计数:当对象被创建的时候都会带有一个引用计数,并且默认的值为1,当引用计数的值为0的时候,对象将被系统销毁。
获得所有权和放弃所有权的方法:
打印计数器:给对象发送 retainCount消息获得当前的引用计数,返回值是无符号长整型,可以使用如下语句打印:NSLog(@“%zi”,[stu retainCount]);


但是因为其他原因,retainCount最小值为1.

获得所有权
alloc:为一个新对象分配内存,并将它的引用计数置为1.调用alloc方法你便拥有了新对象的所有权。
retain:是对象的引用计数+1,并获得对象的所有权。
copy:制造原有对象的副本,该副本的引用计数为1,调用拥有该副本的所有权,并在赋值前释放原有对象,然后在进行赋值。其实,copy也可以这样理解,如果指针A和指针B不想相互牵扯,A管理A的内存,B管理B的内存,copy这是为这个而生。
放弃所有权
release:是对象的引用计数减1,并且在哪个时候放弃对象的所有权。
autorelease:是对象的引用计数在未来的某个时候减1,并在那个时候放弃对象的所有权,而当前引用计数并没有变。
当引用计数为0的时候,系统则会自动调用继承自NSObject的 dealloc 方法,释放所内存,然后为了能够释放由对象创建或保持的实例变量或者其他对象,需要复写Dealloc方法,但是不建议直接调用dealloc方法,因为这个是由系统进行调用的。
内存管理原则
# 谁创建,谁释放(水污染,谁治理),如果你通过alloc、new或copy来创建一个对象,那么你必须调用release或autorelease。
# 一般来说,出了alloc、new或copy之外的方法创建的对象都被声明了autorelease。
# 谁retain,谁release。只要你调用了retain,无论这个对象是如何生成的,你都要调用release。
对象之间的内存管理

3、自动引用计数(ARC)


Wait! 此处暂时留空