一、内存管理的方式
     1、iOS应用程序出现Crash(闪退),90%的原因是因为内存问题。
     2、内存问题:
     1)野指针异常:访问没有所有权的内存,如果想要安全的访问,必须确保空间还在。
     2)内存泄露:空间使用完之后没有及时释放。
     3)过度释放:对同一块存储空间释放多次,立刻Crash。
     4)内存溢出:所有存储空间被占用。
     3、内存管理方式
          1)垃圾回收机制(Garbage-Collection)。
            Java开发中一直使用的就是垃圾回收技术,Mac OS开发中使用,iOS开发为了代码时效性而不使用垃圾回收技术。
          程序员只需要开辟内存空间,不需要释放,由系统判断哪些空间不再被使用,并回收这些内存空间,自动完成垃圾回收。
          2)MRC(Manual Reference Counting)。
          人工引用计数:内存的开辟和释放都由程序代码进行控制。相对于垃圾回收来说,对内存的控制更加灵活,可以在需要释放的时候及时释放。
          3)ARC(Auto Reference Counting)。
          自动引用计数:iOS 5.0的编译器特性,他允许用户只开辟空间,不用去释放空间。它不是垃圾回收!它的本质还是MRC,只是编译器帮程序员默认加了释放的代码。
          4)iOS支持两种内存管理方式:ARC和MRC。
          5)MRC的内存管理机制是:内存技术,都是引用计数来管理内存。
          6)ARC是基于MRC的。 
二、引用计数机制,影响引用计数的各种方法
     1、引用计数    
          p2、p3、p4即为野指针。
          OC采用引用计数机制管理内存,每个对象都有一个引用计数器,用来记录当前对象的引用次数。当一个新的引用指向对象时,引用计数器就加1,当去掉一个引用时,引用计数就减1。当引用计数到零时,表示没有任何对象对该对象引用,那么这时候系统会自动调用dealloc方法来回收该对象的存储空间/该对象的空间就被系统回收。
     2、影响引用计数的方法
          retainCount 获取对象的引用计数。(retainCount它是MRC才有的机制,所以如果使用需要将ARC改为MRC)。
             使计数器加1的方法:alloc,retain,copy。
          1)+alloc 开辟内存空间,让被开辟的内存空间的引用计数从0变为1.
          2)-retain 引用计数加1,如果对象之前引用计数为1,retain之后变为2,如果引用计数是5,retain之后变为6。
          3)-copy 把某一对象的内容拷贝一份,拷贝出新的对象,原有对象的引用计数不变,新的对象的引用计数变1。
          使计数器减1的方法:release,autorelease。
          4)-release 引用计数立即减1,如果对象之前的引用计数为4,release之后变为3,如果之前引用计数是1,release之后变为0,内存被系统回收。
          5)-autorelease 未来的某一时刻引用计数减1,如果对象之前引用计数为4,autorelease之后仍然为4,未来某个时刻会变为3。
     3、autoreleasepool的使用
          通过autoreleasepool自动释放池,控制autorelease对象的释放。向一个对象发送autorelease消息,该对象就会添加到离autorelease最近的自动释放池中,当自动释放池销毁时,为池中的每一个对象发送release消息。
 
三、内存管理的基本原则
     1、凡是使用了alloc、retain或者copy让内训的引用计数增加了,就需要使用release或者autorelease让内存的引用计数减少。在一段代码内,增加和减少的次数要相等。
     2、如果增加的次数大于减少的次数,会造成内存泄漏。
Person *person10 = [[Person alloc] init];
        [person10 retain];
        [person10 release];
 
Person *person13 = [[Person alloc] init];
        person13 = nil;
        [person13 release];
        // [nil release]此消息不能发送
     3、如果增加的次数小于减少的次数,会造成过度释放。
Person *person11 = [[Person alloc] init];
        [person11 release];
        [person11 release];
     4、如果增加的次数等于减少的次数,还继续访问,造成野指针问题。
Person *person12 = [[Person alloc] init];
        [person12 retain];
        [person12 release];
        [person12 release];
        NSLog(@"person12 = %lu", person12.retainCount);
 
四、协议
     1、Protocol(协议),是iOS开发中常用的技术。
     2、协议是一套标准(一堆方法的声明),只有.h文件。就像一张任务清单(或便利贴),上面写了一堆需要处理的事。清单交给谁,谁就要去完成清单上规定的任务。
     3、接受协议的类实现协议中定义的方法。即:清单交给谁,谁就要去完成清单上规定的任务。
     4、协议中的方法默认是必须实现的,即@required。关键字@optional修饰的方法是可选的,可实现也可不实现。
     5、协议的使用:在类的.h文件中,在当前类父类的后面使用一对尖括号<>,遵循协议,一个类可以遵循多个协议,每个协议用逗号隔开。
     @interface Person : NSObject<MarryProtocol,NSCopying>
五、内存拷贝
     1、跟retain不同,一个对象想要copy,生成自己的副本,需要服从NSCopying协议,定义copy的细节(如何copy)。如果类没有接受NSCopying协议而给对象发送copy消息,会引起crash。
     2、NSCopying协议中的方法:
@protocol NSCopying

- (id)copyWithZone:(nullable NSZone *)zone;

@end
     3、根据copyWithZone:方法的实现不同,拷贝分为三种类型:
          1)伪拷贝:拷贝地址,相当于retain操作,引用计数加1。     
           - (id)copyWithZone:(NSZone *)zone {
    return [self retain];
          2)浅拷贝:对象开辟新的空间,但是两个对象的实例变量指向同一块空间。
           - (id)copyWithZone:(NSZone *)zone {
    Person *copyPer = [[Person allocWithZone:zone] init];
    copyPer.name = self.name;
    copyPer.gender = self.gender;
    return copyPer;
}
          3)深拷贝:对象开辟新的空间,两个对象的实例变量也指向不同的空间。
           - (id)copyWithZone:(NSZone *)zone {
    Person *copyPer = [[Person allocWithZone:zone] init];
    copyPer.name = [self.name mutableCopy];
    copyPer.gender = [self.gender mutableCopy];
    return copyPer;
}
六、总结
     1、OC借助了引用计数机制去管理内存,凡是使用了alloc、copy、retain等方法,增加了引用计数,就要使用release和autorelease减少引用计数,引用计数为0的时候,对象所占的内存,被系统回收。
     2、autorelease是未来某个时间(autoreleasepool销毁)引用减1,不是即时的。
     3、不是任何对象都可以接受copy消息,只有接受了NSCopying协议的对象才能接收copy消息。

iOS学习之Object-C语言内存管理的更多相关文章

  1. iOS学习08之C语言内存管理

    本次主要学习和理解C语言中的内存管理 1.存储区划分 按照地址从高到低的顺序:栈区,堆区,静态区,常量区,代码区 1> 栈区:局部变量的存储区域 局部变量基本都在函数.循环.分支中定义 栈区的内 ...

  2. 【转】iOS夯实:ARC时代的内存管理

    iOS夯实:ARC时代的内存管理 什么是ARC Automatic Reference Counting (ARC) is a compiler feature that provides autom ...

  3. iOS夯实:ARC时代的内存管理

    iOS夯实:ARC时代的内存管理 文章转自 ARC时代的内存管理 什么是ARC Automatic Reference Counting (ARC) is a compiler feature tha ...

  4. Go语言内存管理(一)内存分配

    Go语言内存管理(一)内存分配 golang作为一种"高级语言",也提供了自己的内存管理机制.这样一方面可以简化编码的流程,降低因内存使用导致出现问题的频率(C语言使用者尤其是初学 ...

  5. 深入理解Linux C语言内存管理

    问题不能拖,我这就来学习一下吧,争取一次搞定. 在任何程序设计环境及语言中,内存管理都十分重要. 内存管理的基本概念 分析C语言内存的分布先从Linux下可执行的C程序入手.现在有一个简单的C源程序h ...

  6. Objective-C 高级编程:iOS与OS X多线程和内存管理

    <Objective-C 高级编程:iOS与OS X多线程和内存管理> 基本信息 原书名: Pro Multithreading and Memory Management for iOS ...

  7. C语言 内存管理(转)

     转自 https://blog.csdn.net/u011616739/article/details/61621815 C语言 内存管理 1.内存分区 C源代码进过预处理.编译.汇编和链接4步生成 ...

  8. 【Spark-core学习之八】 SparkShuffle & Spark内存管理

    [Spark-core学习之八] SparkShuffle & Spark内存管理环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 ...

  9. iOS学习之Object-C语言内存管理高级

    一.属性的内存管理

随机推荐

  1. 《Unix/Linux日志分析与流量监控》书稿完成

    <Unix/Linux日志分析与流量监控>书稿完成 近日,历时3年创作的75万字书稿已完成,本书紧紧围绕网络安全的主题,对各种Unix/Linux系统及网络服务日志进行了全面系统的讲解,从 ...

  2. javacript 优化2

    上面一篇文章大致介绍了一些javascript当中使用的一些小技巧,当下这篇文章继续介绍一下内存管理.松散耦合.性能方面的一些小知识.为避免错误应该注意的点 内存管理 1.循环引用 如果循环引用中包含 ...

  3. C# (GDI+相关) 图像处理(各种旋转、改变大小、柔化、锐化、雾化、底片、浮雕、黑白、滤镜效果) (转)

    C#图像处理   (各种旋转.改变大小.柔化.锐化.雾化.底片.浮雕.黑白.滤镜效果)     一.各种旋转.改变大小   注意:先要添加画图相关的using引用.   //向右旋转图像90°代码如下 ...

  4. Windows phone 8 学习笔记(4) 应用的启动(转)

    Windows phone 8 的应用除了可以直接从开始菜单以及应用列表中打开外,还可以通过其他的方式打开.照片中心.音乐+视频中心提供扩展支持应用从此启动.另外,我们还可以通过文件关联.URI关联的 ...

  5. linux 编译,链接和加载

    1.   序 最近在折腾各种.so,碰到了一些问题,一开始对于很多错误也没有头绪,茫然不知所措.索性化了一天多时间将<<程序员的自我修养—链接.装载与库>>中部分内容略读了一遍 ...

  6. JAVA嵌入运行Groovy脚本

    摘自: http://shift-alt-ctrl.iteye.com/blog/1938238 . 最近设计一个数据统计系统,系统中上百种数据统计维度,而且这些数据统计的指标可能随时会调整.如果基于 ...

  7. Solaris的vi

    进入输入模式i: 在光标之前插入a: 在光标之后插入o: 在下面新建一行输入I: 光标移动到本行首插入A: 光标移动到本行末尾插入O: 在上面新建一行输入 移动光标M:移到屏幕中间一行的行首L:移到屏 ...

  8. MFC 线程创建方式

    MFC 分UI线程和工作线程,一般现在的应用程序都是一个主UI线程和N个工作线程来完成工作.主UI线程获取到工作线程发送的信息来刷新界面. 不过因为工作需要,MFC有要维护的项目,因此就学习一下MFC ...

  9. 搭建高性能计算环境(二)、远程登录Linux服务器

    一般操作Linux系统都是通过远程登录使用的,本节介绍几种远程登录Linux.上传下载文件的工具. 1. Secure Shell SSH 简单方便.既能使用命令行登陆也能传文件,免费. 打开SSH ...

  10. jquery图片轮播,单张图片轮播时间不同

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...