编程语言-关于Automatic Reference Counting技术的深度解释?

编程语言-关于Automatic Reference Counting技术的深度解释?

清晨说ぺ晚安 发布于 2017-02-22 字数 269 浏览 1131 回复 2

目前很多语言都开始有这种机制,想java、C#、objectC等都实现自动垃圾回收,我们知道Automatic Reference Counting (ARC) 是一个编译期的技术,利用此技术可以简化内存管理方面的工作量,但是从最终代码的实现上和不适用自动内存管理有什么本质的去表,性能、代码大小求详细的解释?

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

晚风撩人 2017-05-09 2 楼

ARC的重点:

它是Compile-time的技术,并不是在runtime用thread去处理
开发者不能再直接使用retain, release, autorelease,改由compiler帮你写这些代码。
所有的property不再使用retain, assign而改用strong, weak取代。
NSAutoreleasePool也要改用特有的 @autoreleasepool{} 来取代。

ARC的工作原理:
在你编译程序时,将内存操作的代码(retain,release或autorelease)自动添加到需要的位置。即底层上使用和Manual Reference Counting(手工引用计数)一样的内存管理机制,但由于是自动帮你在编译时添加内存操作的代码,从而简化了编程的工作。

由此可见,ARC会让开发者减少了手动内存操作的逻辑,而其因为是在编译期的处理,并不会影响运行时的性能。

简要说明一下,不能算是深度解释。

补充一个地址:ARC(Automatic Reference Counting )技术概述

泛泛之交 2017-04-08 1 楼

Automatic Reference Counting (ARC), 自动引用计数,是开发程序时的一个编译级别的特性,用于自动内存管理。

自动引用计数
1. 关于本文档
1.1. 目标

本文的首要目标是作为自动引用计数(ARC,以下译文均简称为ARC)技术的完全说明文档,
开发者应该能够根据该文档编写出满足ARC技术的Objective-C的编译器或者运行时环境.

本文的另一个目标是介绍ARC技术的理论基础,说明为什么要以这样的方式实现ARC技术.
本文描述的内容仅限于技术目的,不应牵扯到商业性的说明当中.

1.2. 背景(本文假定读者基本熟悉C语言)

块语法(Blocks)是C语言的一个扩展,用以创建匿名函数.编程人员通过块指针(block pointer)获取和传递块对象(block objects),
块指针在形式上跟普通的指针一样.一个块中可能包含局部变量,如果是这样,该局部变量必须是动态分配的.块对象的初始化和内存分配的操作在栈上完成,
但是运行时环境会提供了一个Block_copy(块拷贝)的函数,通过一个给定的块指针,将整个块对象拷贝到堆上并设置其引用计数为1并返回一个新的块指针,
如果这个块对象已经在堆上了(通过指针来判断),那么引用计数会加1.对应于块拷贝函数有一个Block_release(块释放)函数,
这个函数的作用是将对象的引用计数减1,如果引用计数为0,则会销毁堆上的对象.

Objective-C包含了很多的语言扩展(注:不仅仅是C的扩展),完全可以被认为是一门新的语言.它是严格遵循C语法的一个超集,同时也在C++上进行了一些扩展,
也产生了一门新的语言Objective-C++.最重要的一点是类的单继承特性(注:现代的类C语言,Java/C#都是仅支持单继承,但允许实现多个协议[接口],Objective-C也是如此)。

Objective-C定义了一种新的类型,被称为对象指针类型(object pointertype).这一新类型包含两个非常重要的内置成员id 和class,id是所有对象指针的最终父类.
Objective-C在运行时不会对对象指针之间的转换进行合法性的检查.程序员可以定义各种各样的类,每个类都是一个新的类型,指向这一类型的指针是一个对象指针.
一个类可以有一个父类, 类的对象指针是其父类的对象指针的子类.一个类也可以包含很多的成员变量,每一个实例化的类对象都包含这些变量.
对应于每个类型T,有一个关联的元类型(metaclass),元类型不包含任何成员变量,T的元类型的父类是T的父类的元类型,元类型是一个全局类(此处不太理解).
每一个类都包含一个全局对象,这个对象的类型是该类的元类型;元类型没有(再)关联其他(元)类型,所以指向这个对象的指针是类类型.

类型的声明以关键字@interface开始,可以包含一组方法(method).一个完整的方法包含返回类型,参数列表和一个选择器(selector),选择器的语法形式是
foo:bar:baz:, 冒号的个数对应于方法参数个数.一个方法可以是一个实例方法,通过一个实例对象进行调用;也可以是一个类方法(静态方法),
通过类型的元类型包含的类型对象进行调用(理解为通过类进行调用即可).方法可以通过一个接收者和一个带参或者无参的选择器进行调用,如以下示例:
[receiverfoo:fooArg bar:barArg baz:bazArg]

这样的方法调用会先查找接收者的实际类型,根据类型查找具有相应名字的方法,如果找不到,会沿继承链向上查找父类的方法,直至找到相应的可执行的方法为止.
接收者也可以是一个类型(这是为什么叫接收者不叫对象的原因),这种调用下执行的是类型的方法,不过也可能是这个类型的父类型的方法,
发生这种情况是因为查找算法先从父类查找而不是从当前调用的类型进行查找方法. 真正动态找到的方法声明可能并不在类型声明中(@interface),
而是在实现(@implementation)中,但是在编译时编译器检查一个方法调用是否合法,仅仅是根据方法在声明中的定义进行检查的,因此会造成以上提及的情况.
方法声明可以通过协议(protocol,Java或C#称为接口)进行分组,协议不关联与任何特定的类型,但是遵循特定协议的类型必须按协议的约定进行实现.
对象指针类型可被限定于特定的协议,这样对象就知道是否支持某个协议.
举例:id<MyDelegate>__unsafe_unretained delegate;

类型扩展(class extensions)是变量和方法的集合,可以将类型的声明分散到多个文件中去,但是在实现文件中,必须要包含所有分散定义的类型扩展的头文件.
Objective-C支持通过类别(Category)进行类型扩展,类别允许方法(不允许变量)在任何一个类型中声明,在类别实现中的方法会自动被加到类型的方法表中去.
类别是在运行时被加载的,类别中声明的方法会替换原有的同名方法,这会导致方法名称冲突,实际编程中需要注意.
通常,对象是在堆上进行分配,对象的生命周期通过引用计数进行管理.引用计数的管理通过两个实例方法实现:Retain,对象引用计数+1
Release,对象应用计数-1,当计数为0时调用对象的dealloc方法.

为了简化这些操作,Objective-C有一个自动释放池(AutoreleasePool)的实现,通过一个线程保留一个将来需要调用release方法的对象本地列表,
任何一个对象可以通过调用autorelease方法加入特定的自动释放池.块指针可以被转换成id类型;块对象通过适当的内存布局使得其兼容于Objective-C对象.
Objective-C有一个内置的类型,所有块对象都可被认为是(is a)这一内置类型的对象,这一类型通过retain方法来调整引用计数,而不是通过Block_copy方法.

![示意图]

[中文版帮助]

官方文档