一、内存管理的方式
     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. php 数组转json格式

    1.php若为关系数组:转化为由花括号包围的对象: 输入:$test = array("1"=>1,"2"=>2,"3"=> ...

  2. 学习总结 java 父子级

    package com.hanqi; //父类 public class Father { // public Father() // { // // } // public Father(Strin ...

  3. 使用Cookie保存商品浏览记录

    数据流程:页面上是商品列表,点击<a href="productServlet">商品名</a> ==>跳转到自定义的servlet中进行处理,先得到 ...

  4. SWFUpload使用指南

    SWFUpload是一个flash和js相结合而成的文件上传插件,其功能非常强大. SWFUpload的特点: 1.用flash进行上传,页面无刷新,且可自定义Flash按钮的样式; 2.可以在浏览器 ...

  5. php获取文件创建时间、修改时间

    filemtime ( string filename ) 返回文件上次被修改的时间,出错时返回 FALSE.时间以 Unix 时间戳的方式返回,可用于 date(). 例如:$a=filemtime ...

  6. .NET平台下,关于数据持久层框架

    在.NET平台下,关于数据持久层框架非常多,本文主要对如下几种做简要的介绍并推荐一些学习的资源: 1.NHibernate 2.NBear 3.Castle ActiveRecord 4.iBATIS ...

  7. 【Framework】深入研究Asp.net页面的生命周期

    介绍 Asp.net是微软.Net战略的一个组成部分.它相对以前的Asp有了很大的发展,引入了许多的新机制.本文就Asp.net页面的生命周期向大家做一个初步的介绍,以期能起到指导大家更好.更灵活地操 ...

  8. Something wrong with FTK OCR

    A case about business secret the suspect took lots of photos and screenshots from BOM, RD papers... ...

  9. dig out deledted chat messages

    One of my friends asked me to do a favor for her. She said her friend deleted some important chat me ...

  10. myeclipse上SVN代码合并详细步骤图解

    1.  在装有svn插件的myeclipse中,在主干上选择需要合并的文件或文件夹 右击 -> 合并(merge) 2. 选择合并类型--合并两个不同的树 Merge -> Next 3. ...