iOS内存管理机制解析之MRC手动引用计数机制

前言:

iOS的内存管理机制ARC和MRC是程序员参加面试基本必问的问题,也是考察一个iOS基本功是

否扎实的关键,这样深入理解内存管理机制的重要性就不言而喻了。

iOS内存管理机制发展史

  • iOS 5以前 :MRC(手动引用计数)
  • iOS 5及以后:ARC (自动引入计数)

MRC机制时代

“谁开辟申请,谁及时合理释放” 面对自己申请的内存空间是要及时进行回收的:

不及时释放会造成什么结果?

对象存储在栈上,可能会大量的占用内存,内存不足造成程序闪退(也就是所说的内存泄露)

不合理释放会造成什么后果?

提前释放掉,倘若后面继续对该对象进行引用操作,会出现崩溃,出现EXC_BAD_ACCESS操作已经释放掉的对象的崩溃提示。(也就是所说的野指针)

MRC机制时代对于iOS程序员来说是有些痛苦的,那么我们深入的解析一下

内存管理原则 —-配对原则

解释:使引用计数(retainCount)+1的时候必须相对应的出现使引用计数-1

怎样使引用计数+1 ?

new copy(mutablecopy) retain alloc

怎样使引用计数-1?

release autorelease

例如:

[对象 release];  reatinCount-1

[对象 retain];   reatinCount+1,并且返回self

判断一个对象是否能被系统回收?

正藏情况下能被系统回收的对象唯一依据是该对象的引用计数(retainCount)为0

再谈谈dealloc函数

     //当实例变量的引用计数为0,系统会自动调用dealloc函数进行摧毁回收
     - (void)dealloc{}

重写dealloc函数时应注意:

  1. 重写dealloc时需要对用父类的dealloc函数
  2. 倘若有子类需要销毁顺序应在父类上面,避免出现不必要的错误
    - (void)dealloc
     {
            [子类变量  release];
            [super dealloc];
    }
    

ARC工程如何转变为MRC工程

YES—->NO

MRC实战中常见错误

准备工作

创建一个工程–>创建一个名为List的类名—>类中创建一个name变量@property NSString *name;—->重写dealloc方法(这样内存运用的得当否直接根据打印看到)

    -(void)dealloc
    {
       NSLog(@"我的内存要被释放了");
       [super dealloc];
    }

1. 使用变量没有遵守配对原则,造成的内存泄露

#import <Foundation/Foundation.h>
#import "List.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {

    List *l=[[List alloc]init];   // reatinCount=1

    [email protected]"苹果";

    NSLog(@"%lu",l.retainCount);

    //[l release];
      }
      return 0;
  }

运行结束后l的引用计数仍然为1,并没有调用dealloc

2.遵守配对原则但由于错误使用nil,造成的内存泄露

     List *l=[[List alloc]init];
     [email protected]"苹果";
    NSLog(@"%lu",l.retainCount);
    l=nil;
    [l release];

在操作类对象的时候喜欢在最后一次release的后面讲对象=nil,避免其他地方引用对象造成崩溃,但放的位置不正确则会出现像上面那样的内存泄露 [l release]此时等价于[nil release],而l的引用计数为1,并没有及时释放

3.提前释放对象,造成野指针操作

 List *l=[[List alloc]init];
    [email protected]"苹果";
    NSLog(@"%lu",l.retainCount);
    List *l1=l;
    [l release];
    NSLog(@"%@",l1.name);

l1=l,此时有两个指针同时指向同一个类地址,当一个指针release造成 reatinCount=0释放 了类的内存空间,而另一个指针也将指向空,就会引发野指针异常

4.当一个对象retainCount已经为0 时,调用retain方法,是不会使得对象起死回生的,同时还会发生野指针操作异常

    List *l=[[List alloc]init];
    [email protected]"苹果";
    NSLog(@"%lu",l.retainCount);
    [l release];
    [l retain];

5.MRC下set和get方法的重写

@interface List : NSObject
{
    NSString *_name;
}
-(void)setName:(NSString *)name;
-(NSString *)name;
@end

@implementation List
-(void)setName:(NSString *)name
{
    if (_name!=name) {
    [_name release];
    _name=[name retain];
    }
}
-(NSString *)name
{
    return _name;
}
@end
时间: 2024-11-10 09:15:35

iOS内存管理机制解析之MRC手动引用计数机制的相关文章

python-面试常用 --变量、内存管理(小整数池,引用计数)

执行Python程序的两种方法 第一种:交互式(jupyter就是对这种进行了封装) 优点:直接给出结果 缺点:无法保存 第二种:命令行式,通过Python解释器输入文本(pycharm对这种进行了封装) 优点:可以保存 缺点:无法及时得到报错反馈 命令行式可以识别任何文本文件,例如:.txt文件..py文件. 命令行式打开的三个步骤 编写Python文件 找到Python文件的路径,把文本从硬盘中读入内存 在内存运行并进行解释(这个时候才会有Python语法的概念,才会打印) 变量 什么是变量

【Bugly干货分享】iOS内存管理:从MRC到ARC实践

Bugly 技术干货系列内容主要涉及移动开发方向,是由Bugly邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 对于iOS程序员来说,内存管理是入门的必修课.引用计数.自动释放等概念,都是与C语言完全不同的.搞明白这些,代码才有可能不 crash.然而就是这么牛逼的内存管理,着实让我这个从 C 转过来的老程序员头疼了一段时间. [C++ 程序员的迷惑和愤怒] iOS 内存管理的核心是引用计数.与众多五年甚至更多以上开发经验的程序员一样,笔者当初是

IOS内存管理

原文链接:http://blog.csdn.net/weiqubo/article/details/7376189 1.  内总管理原则(引用计数)    IOS的对象都继承于NSObject,   该对象有一个方法:retainCount ,内存引用计数. 引用计数在很多技术都用到: window下的COM组件,多线程的信号量,读写锁,思想都一样.       (一般情况下: 后面会讨论例外情况)    alloc      对象分配后引用计数为1    retain    对象的引用计数+1

iOS内存管理(objective-c)

移动app开发中,由于移动设备内存的限制,内存管理是一个非常重要的话题.objective-c的内存管理,不仅是面试当中老生常谈的一个必问话题,也是日常项目开发中,特别需要重视的环节.对于笔者这种以java语言入门编程世界的开发者来说,习惯了垃圾收集器的自动化管理,对于oc的引用计数器管理方式,还是需要花功夫来学习和运用. 1. ARC 和 非ARC oc的内存管理方式,分为ARC(automatic reference counting自动引用计数)和非ARC模式.Apple 在 Xcode

IOS内存管理retain,assign,copy,strong,weak

IOS内存管理retain,assign,copy,strong,weak IOS的对象都继承于NSObject, 该对象有一个方法:retainCount ,内存引用计数. 引用计数在很多技术都用到: window下的COM组件,多线程的信号量,读写锁,思想都一样. (一般情况下: 后面会讨论例外情况)alloc 对象分配后引用计数为1retain 对象的引用计数+1copy copy 一个对象变成新的对象(新内存地址) 引用计数为1 原来对象计数不变 release 对象引用计数-1 如果为

浅谈iOS内存管理机制

iOS内存管理机制的原理是引用计数,引用计数简单来说就是统计一块内存的所有权,当这块内存被创建出来的时候,它的引用计数从0增加到1,表示有一个对象或指针持有这块内存,拥有这块内存的所有权,如果这时候有另外一个对象或指针指向这块内存,那么为了表示这个后来的对象或指针对这块内存的所有权,引用计数加1变为2,之后若有一个对象或指针不再指向这块内存时,引用计数减1,表示这个对象或指针不再拥有这块内存的所有权,当一块内存的引用计数变为0,表示没有任何对象或指针持有这块内存,系统便会立刻释放掉这块内存. 其

iOS内存管理(ARC,MRC)

iOS内存管理方式: ARC Automatic Reference Counting 自动引用计数 MRC Manual Reference Counting 手动引用计数 更改管理方式: 内存管理的问题: 1.内存泄露:不再需要的对象没有释放. 2.野指针:正在使用的对象提前释放. 引用计数: 1.每一个对象上都有一个引用计数器 2.当对象出生时引用计数器为1 3.当对象调用retain方法时引用计数器+1 4.当对象调用release方法时引用计数器-1 5.当一个对象引用计数为0时,这个

iOS内存管理 ARC与MRC

想驾驭一门语言,首先要掌握它的内存管理特性.iOS开发经历了MRC到ARC的过程,下面就记录一下本人对iOS内存管理方面的一些理解. 说到iOS开发,肯定离不开objective-c语言(以下简称OC).OC的内存管理机制叫做引用计数,就是一块内存地址可以同时被多个对象引用,每引用一次,引用计数都会递增1,当对象每解除一次引用,引用计数就会递减1,直到引用计数为0时,系统才会讲这块内存地址回收释放掉,这与C/C++语言有些不同,但是它们都遵守同一个内存管理法则:谁申请,谁释放. 在早些时候,iO

谈谈ios内存管理--持续更新

本文主要谈谈ios内存管理的发展脉络,不足之处,还请指教,相互学习交流.做ios开发,永远无法避开内存管理,无论我们是否有意识去考虑这个事情,但是只要我们写了OC程序,那么就与内存管理有关. 一.内存管理是做什么的? 二.内存管理方式一:MRC (一)引用计数器 (二)原则 (三)alloc.new.copy.mutableCopy.retain.release.dealloc alloc内部实现 引用计数表 (四)autorelease 三.内存管理方式二:ARC (一)__strong (二