Objective-C提供了两种内存管理机制MRC(Mannul Reference Counting)和ARC(Automatic Reference Counting),为Objective-C提供了内存的手动和自动管理。下面我们来讲解MRC和ARC的基本概念以及自己的理解,欢迎大家指正!!!

一、前言

在讲述MRC和ARC之前,我们先来看一下Objective-C的引用计数式的内存管理方式。下面是一些特点:

  1. 自己生成的对象,自己持有。(通过alloc/new/copy/mutableCopy等方法)例如:NSObject *obj = [[NSObject alloc]init];
  2. 不是(非)自己生成的对象,自己也能持有:NSMutableArray *array = [NSMutableArray array];
  3. 无法释放非自己持有的对象

1.自己生成的对象,自己持有

在iOS内存管理中,有四个这样的关键字:new、alloc、copy、mutableCopy,如果自身使用这些关键字的时候来产生对象,那么创建完之后,自身也就有了对象。

    // 使用了alloc分配了内存,obj指向了对象,该对象本身引用计数为1,不需要retain
id obj = [[NSObject alloc] init];
// 使用了new分配了内存,objc指向了对象,该对象本身引用计数为1,不需要retain
id obj = [NSObject new];

2.非自己生成的对象,自己也能持有

    // NSMutableArray通过类方法array产生了对象(并没有使用alloc、new、copy、mutableCopt来产生对象),因此该对象不属于obj自身产生的
// 因此,需要使用retain方法让对象计数器+1,从而obj可以持有该对象(尽管该对象不是他 产生的)
id obj = [NSMutableArray array];
[obj retain];

3.无法释放非自己持有的对象

 // 释放一个不属于自己的对象
id obj = [NSMutableArray array]; // obj没有进行retain操作而进行release操作,然后autoreleasePool也会对其进行一次release操作,导致奔溃。
[obj release];

针对[NSMutableArray array]方法取得对象方法,自己并不会持有对象,在底层是这样实现的

+ (id)object {
//自己持有对象
id obj = [[NSObject alloc]init]; [obj autorelease]; //取得的对象存在,但自己不持有对象
return obj;
}

使用了autorelease方法,将obj对象注册到autoreleasePool中,不会立即释放,当pool结束时,再自动调用release。只有这样达到取得对象存在,而自己不持有对象。

下面是来拓展一个问题:[className new]与[[className alloc] init]区别?

面对区别,我么首先来看一下两个的源码。

+ new
{
id newObject = (*_alloc)((Class)self, );
Class metaClass = self->isa;
if (class_getVersion(metaClass) > )
return [newObject init];
else
return newObject;
} //而 alloc/init 像这样:
+ alloc
{
return (*_zoneAlloc)((Class)self, , malloc_default_zone());
}
- init
{
return self;
}

通过上面的源码,我们可以发现[className new]与[[className alloc] init]基本是等同的。

区别也在于alloc 分配内存的时候使用了zone方法。zone方法是给对象 分配内存的时候,把要关联的对象分配到一个相邻的内存区域,这样调用消耗很少的代码,提高了程序的处理速度。

大家发现,如果使用new的时候,初始化方法就会被固定住,只能调用init,如果要想调用initXXX方法怎么办,这样就不行了。

总结:采用new的方式只能通过默认的init方法完成初始化;采用alloc的方式可以使用其他的定制方法。

MRC

retain:作用是将内存数据被指向的一个指针变量,引用计数retainCount + 1

release:作用是引用计数减1,也即是retainCount -1,

autorelease:作用是将内存的管理放到autoreleasepool中去

其中retain和release操作的是引用计数,当引用计数为0时,便会自动释放内存。

//如果Number为预定义的类

Number *num = [Number alloc]init;

Number *num2 =  [num retain];//此时引用记数+1,现为2

[num2 release];//num2为-1,现为1

如果再次调用[num2 release]引用计数为0

 ARC

在我们项目中,打开ARC的方式与关闭ARC的方式如下:

选择Targets -> Compile Phases -> Compile

  • 打开ARC:-fobjc-arc
  • 关闭ARC:-fno-objc-arc

ARC的修饰符

Objective-C的ARC提供了__weak,__strong,__autoreleasing和__unsafe_unretained。下面我们一起看一下:

__weak

代表的弱引用,对象在被释放的时候,指向它的弱引用会自动被置为nil。这样可以防止野指针的产生,__weak也被用于delegate关系中防止循环引用。

__strong

代表的是强引用,如果在声明引用的时候,不加入修饰符,那么默认是强引用。

__autoreleasing

代表在autorelease pool中自动释放对象的引用,和MRC中的autorelease用法是一样的。但是需要注意一点:定义的property时不能使用这个修饰符,因为任何一个对象的property都不会是autorelease型的。

__unsafe_unretained

主要是针对iOS 4,现在已经退出了,大家可以不要深入了解。

以上就是ARC与MRC的基本内容,希望对大家有所帮助。

下一步将讲述MRC-block以及ARC-block的区别,继续探讨ARC与MRC。

内存管理-MRC与ARC详解的更多相关文章

  1. Objective-c的内存管理MRC与ARC

    Objective-c的内存管理MRC与ARC   Objective-c中提供了两种内存管理机制MRC(MannulReference Counting)和ARC(Automatic Referen ...

  2. iOS-旧项目中手动内存管理(MRC)转ARC

    在ARC之前,iOS内存管理无论对资深级还是菜鸟级开发者来说都是一件很头疼的事.我参 加过几个使用手动内存管理的项目,印象最深刻的是一个地图类应用,由于应用本身就非常耗内存,当时为了解决内存泄露问题, ...

  3. ios新特征 ARC详解

    IOS ARC 分类: IOS ARC2013-01-17 09:16 2069人阅读 评论(0) 收藏 举报   目录(?)[+]   关闭工程的ARC(Automatic Reference Co ...

  4. redis cluster管理工具redis-trib.rb详解

    redis cluster管理工具redis-trib.rb详解 来源 http://weizijun.cn/2016/01/08/redis%20cluster%E7%AE%A1%E7%90%86% ...

  5. OC内存管理(MRC)

    首先说明一下几块存储区域: 栈区(局部变量.函数参数值) 堆区(对象.手动申请/释放内存) BSS区(未初始化的全局变量.未初始化的静态数据) 常量区(字符串常量以及初始化后的全局变量.初始化后的静态 ...

  6. [转载]windows任务管理器中的工作设置内存,内存专用工作集,提交大小详解

    windows任务管理器中的工作设置内存,内存专用工作集,提交大小详解 http://shashanzhao.com/archives/832.html 虽然是中文字,但是理解起来还是很困难,什么叫工 ...

  7. KVM镜像管理利器-guestfish使用详解

    原文  http://xiaoli110.blog.51cto.com/1724/1568307   KVM镜像管理利器-guestfish使用详解 本文介绍以下内容: 1. 虚拟机镜像挂载及w2k8 ...

  8. mysql用户授权、数据库权限管理、sql语法详解

    mysql用户授权.数据库权限管理.sql语法详解 —— NiceCui 某个数据库所有的权限 ALL 后面+ PRIVILEGES SQL 某个数据库 特定的权限SQL mysql 授权语法 SQL ...

  9. 【转】MySQL用户管理及SQL语句详解

    [转]MySQL用户管理及SQL语句详解 1.1 MySQL用户管理 1.1.1 用户的定义 用户名+主机域 mysql> select user,host,password from mysq ...

随机推荐

  1. 4.23 Linux(3)

    2019-4-23 19:03:53 买的服务器第三天感觉超爽!! 发现学习Linux超爽,有种操作的快感!!!!!是Windows比不了的!! 阿里巴巴镜像源 : https://opsx.alib ...

  2. Ubuntu出现卡logo、卡住、黑屏无法正常启动、屏幕和键盘背光无法调节等一系列问题?可能是NVIDIA显卡驱动没装好

    也不知道是幸运还是不幸,我从一开始接触ubuntu就遇到这一系列的问题, 而且一直没有一个彻底解决的办法,搞得我无比头疼,也害得我重装了无数遍系统... 国际惯例,只按照个人习惯和喜好来写,对某些人来 ...

  3. laravel-elasticsearch 全文搜索设置

    1.首先安装 jave环境 jdk 下载地址 ,我用的是最新版本的,有时版本要跟elasticsearch对应 2.安装elasticsearch 下载地址 3.安装Laravel scout 全文搜 ...

  4. Reactjs组件中的方法为什么绑定this?

    前言:Reactjs中的定义的方法其实是基于实例的原型方法:es6默认严格模式   问题:在Reactjs组件中写入以下代码,那么执行结果会是什么呢? ··· 结果是这样的: 对的,你没看错,不是do ...

  5. CABaRet: Leveraging Recommendation Systems for Mobile Edge Caching

    CABaRet:利用推荐系统进行移动边缘缓存 本文为SIGCOMM 2018 Workshop (Mobile Edge Communications, MECOMM)论文. 笔者翻译了该论文.由于时 ...

  6. go 语言的序列化与反序列化

    与c 语言一样, 在网络编程中, go语言同样需要进行序列化与反序列化 在c语言中, 通常需要一块内存缓冲区用来收 发数据.缓冲区一般定义成char *buff类型. 当需要发送 数据时, 直接使用m ...

  7. AIO系列文档(2)----TIO使用

    AIO系列文档(1)----图解ByteBuffer中介绍了ByteBuffer用法,下面通过介绍t-io介绍如何使用: hello world例子简介 本例子演示的是一个典型的TCP长连接应用,代码 ...

  8. Trie树详解及其应用

    一.知识简介        最近在看字符串算法了,其中字典树.AC自动机和后缀树的应用是最广泛的了,下面将会重点介绍下这几个算法的应用.      字典树(Trie)可以保存一些字符串->值的对 ...

  9. [Swift]LeetCode21. 合并两个有序链表 | Merge Two Sorted Lists

    Merge two sorted linked lists and return it as a new list. The new list should be made by splicing t ...

  10. [Swift]LeetCode144. 二叉树的前序遍历 | Binary Tree Preorder Traversal

    Given a binary tree, return the preorder traversal of its nodes' values. Example: Input: [1,null,2,3 ...