戏言:

iOS开发已经到了一个ARC时代,一般不需要我们过多的去关注内存是怎么分配,怎么管理的。很长一段时间,我也不知道内存管理是什么鬼,但如果遇到这方面的问题,却找不到解决办法确实很头疼的。So,还是静下心来,好好学习吧,毕竟内功才是体现水平。

1. 引用计数
            对于一块动态申请的内存,有一个人(指针)使用,就给这个内存的计数器加1,使用完成后,就给这个计数器减1,当这个内存的引用计数为0了,我们再释放他,这样,上面的问题就解决了。OC,就是使用引用计数这种方式来管理内存的。

生动的理解就是:举一个生活中的例子,我们一起去水库边烧烤,我把火点着了,当我们正在“水深火热”的烤着肉,一个电话来了,媳妇让我回家。于是,我跟你们说,你们懂的,哥要回去了,为了防止引发火灾,我要把火扑灭了。我相信,此时你们打死我的心都有。
        我们能不能想到更好的方法,我不浇灭火,又不会引起火灾?
        计数,虽然火是我生的,但我们有10个人一起用。那么,这堆火的计数为10,如果我,或者任何一个同学走了,让计数减1,变成9,8,7...这样,直到最后一个同学走,他在走之前将火灭了就好了。            这就是OC的内存管理方式,引用计数。

2.内存管理的黄金法则
            对于引用计数来说,有一套内存管理的黄金法则:
            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/retain/copy/mutableCopy, 创建了对象
    那么就必须使用release进行释放,
        ———谁创建,谁负责释放

3.retain与retainCount
        retain,将对象进项保留操作,也就是使对象的引用计数加1。
        retainCount,打印一个对象的引用计数。


       DSDog*dog=[[DSDog alloc]init];
NSLog(@"%lu",[dog retainCount]);//1 含有init,引用计数加1
DSDog *dog2=[dog retain]; NSLog(@"%lu",[dog2 retainCount]);//2 对象retain,引用计数加1
[dog2 release];
NSLog(@"%lu",[dog2 retainCount]);//1 release,引用计数减1
[dog release]; // 变为0 ,销毁对象

4.MRC和ARC
            ARC   (Automatic Reference Counting),自动引用计数,由xcode,帮我们去管理内存。
            MRC  (Manual  Reference Counting),手动引用计数,我们手动管理内存。

Xcode 5.0  以后的版本默认是ARC模式

工程创建的时候是ARC的,我们如果想要MRC,需要进行如下设置。
            选中工程 - target - Bulid Settings - 搜索:automatic reference counting或auto,将Objective-C Automatic Reference Counting改为NO。

5.@property retain,assign,copy展开

5.1@property (nonatomic, retain) DSDog *dog; 用来修饰ObjC对象。

则会展开如下:
       - (void)setDog:(DSDog *)dog
        {
                if (_dog != dog)
                {
                        [_dog release];
                        _dog = [dog retain];
                }
        }
5.2 assign展开:简单数据类型

@property (nonatomic, assign) DSDog *dog;

assign是直接复制,则会展开如下:
    //简单数据类型 ,OC的内存管理对于简单的数据类型 int\float…, OC无效
    - (void)setDog:(DSDog *)dog
    {
        _dog = dog;
    }

5.3 copy展开  , 复制一份原来的对象

//copy 多用于字符串,Dict、Array
    @property (nonatomic, copy)NSString *name;
    - (void)setName:(NSString *)name
    {
        if (_name != name)
        {
            [_name release];
            _name = [name copy];
        }
    }
6.自动释放池

原理:对象接收到autorelease消息时,它会被添加到了当前的自动释放池中,当自动释放池被销毁时,会給池里所有的对象发送release消息。

ObjC提供两种方法创建自动释放池:
  方法一:使用NSAutoreleasePool来创建

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc]init];
//这里写代码
[pool release];
方法二:使用@autoreleasepool创建
  @autoreleasepool {
//这里写代码
} 7.weak:ARC新引入修饰词,可代替assign,比assign多增加一个特性
strong:ARC新引入修饰词,可代替retain
 

OC第七节——内存管理的更多相关文章

  1. 七.OC基础加强--1.内存管理 2.野指针,内存泄露 3.set方法的内存管理 4.@property参数 5.@class和循环retain的使用 6.NSString的内存管理

    1,内存管理简单介绍 1,为什么要有内存管理? malloc selloc dealloc```需要回头复习 一般的内存 4s 是512m内存:6 是1024m内存: 当内存过大时,会耗尽内存.出现程 ...

  2. OC语言-05-OC语言-内存管理

    一.引用计数器 1> 栈和堆 栈 ① 主要存储局部变量 ② 内存自动回收 堆 ① 主要存储需要动态分配内存的变量 ② 需要手动回收内存,是OC内存管理的对象 2> 简介 作用 ① 表示对象 ...

  3. OC基础15:内存管理和自动引用计数

    "OC基础"这个分类的文章是我在自学Stephen G.Kochan的<Objective-C程序设计第6版>过程中的笔记. 1.什么是ARC? (1).ARC全名为A ...

  4. oc 第五天(内存管理)

    OC的重点: 内存管理 1 基本原理     OC的内存回收机制是和JAVA的自动回收机制是不同的,它有两种模式,或者准确的说是同 一种模式的两种不同体现,下面简单总结下. 1手动内存回收       ...

  5. OC学习篇之---内存管理介绍和使用

    在之前的一片文章我们说了OC中谓词操作:http://blog.csdn.net/jiangwei0910410003/article/details/41923507,从今天开始我们就来看一下OC中 ...

  6. 第七章 内存管理单元MMU介绍

    7.1 内存管理单元MMU介绍 7.1.1 S3C2410/S3C2440 MMU特性 负责虚拟地址到物理地址的映射,并提供硬件机制的内存访问权限检查 特性: 与ARM V4兼容的映射长度.域.访问权 ...

  7. Android Training精要(七)内存管理

    在2.3.3及以下版本: 通過定義兩個整形變量來檢測bitmap是否display過或者已經在緩存中 下面的代碼當bitmap滿足兩個條件就被回收掉: 1. 兩個整形變量都變為0 2. bitmap不 ...

  8. block本质探寻七之内存管理

    说明: <1>阅读本问,请参照block前述文章加以理解: <2>环境:ARC: <3>变量类型:基本数据类型或者对象类型的auto局部变量: 一.三种情形 //代 ...

  9. 重读金典------高质量C编程指南(林锐)-------第七章 内存管理

    2015/12/10补充: 当我们需要给一个数组返回所赋的值的时候,我们需要传入指针的指针.当我们只需要一个值的时候,传入指针即可,或者引用也可以. 结构大致如下: char* p = (char*) ...

随机推荐

  1. Java垃圾收集学习笔记

    (1)除了释放不再被引用的对象,垃圾收集器还要处理 堆碎块 .请求分配新对象时可能不得不增大堆空间的大小,虽然可以使用的空闲空间是足够的,但是堆中没有没有连续的空间放得下新对象.可能会导致虚拟机产生不 ...

  2. Struts学习总结-02 类型转换

    一 类型转换 input.jsp <%@ page language="java" import="java.util.*" pageEncoding=& ...

  3. mysql php query steps

    1.mysql connect $db=new mysqli ('localhost','database','user','password'); 2. query $query=select id ...

  4. CSS-论css如何纯代码实现内凹圆角

    background-image: radial-gradient(200px at 50px 0px, #fff 50px, #4169E1 50px); 这是做内凹圆角的核心代码,就是背景图的ra ...

  5. Ubuntu 12.04 root账户开启及密码重设

    以普通用户登录,root账号的开启.关闭和密码设置,命令如下: sudo passwd -u root # 启用root账户 sudo passwd root # 设置root 密码(包括重设) su ...

  6. SVM支持向量机的高维映射与核函数-记录毕业论文2

    上一篇博客将了在数据集线性可分的情况下的支持向量机,这篇主要记录如何通过映射到高维解决线性不可分的数据集和如何通过核函数减少内积计算量的理论思想. [5]径向基函数的核函数:https://www.q ...

  7. WinForm------窗体初始化位置的显示

    在窗体的构造方法里面添加 public Form2() { InitializeComponent(); //指定窗口初始化时的位置(计算机屏幕中间) this.StartPosition = For ...

  8. Centos: 修改 yum安装的mysql路径

    1.使用命令service mysqld stop 停止mysql查看mysql数据库的默认路径:/var/lib/mysql使用cp -afir  /var/lib/mysql/*   /usr/l ...

  9. re正则表达式7_{}

    curly brackets {} instead of one number, you can specify a range by writing a minimum,a comma,and a ...

  10. Unity3D Sprite Draw Call合批规则

    只要材质相同,并Sprite在同一Atlas里,就可以合批. 不论Sorting Layer不同,还是Sorting Order不同. 材质相同的两个不同Sorting Order之间插入一个不同材质 ...