iOS ARC学习汇总

简介:

ARC

ARC是什么

ARC是iOS 5推出的新功能,全称叫 ARC(Automatic Reference Counting)。简单地说,就是编译阶段自动做了retain/release,原先需要手动添加的用来处理内存管理的引用计数的代码可以自动地由编译器完成了。就ARC并不是GC,不是运行时内存管理,不会做malloc/free的工作,它只是一种代码静态分析(Static Analyzer)工具。
比如,我们生成一个对象:


addretain.png


编译器会给我们添加上retain/release/autorelease


add2.png

比如,block的写法,编译器背后给我们做的事:


add3.png

ARC之前的手工管理内存

我们需要手动retain和 release对象。如下:

 // First you create an object, which you then own ("retain")
 // Retain count = 1
 Customer *newCustomer = [[Customer alloc] init];

 // Next, you do something with the new object, such as add it to an 
 // array, which also now retains it. Retain count = 2

 [customerArray addObject:newCustomer];

 // When finished with the object, you relinquish (release) ownership. 
 // Retain count = 1

 [newCustomer release];

 // At some point customerArray is also released, releasing all of the
 // objects it contains. Retain count = 0, and the original object is 
 // finally deallocated

 [customerArray release];

这个过程很容易出错。所以苹果引入ARC,在编译阶段自动帮我们做retain/release的工作,如下图,减少了很多代码。


add4.png

手工引用计数规则

  • 用“alloc”, “new”, “copy”, or “mutableCopy”等方法生成object的时候,object 的引用计数为1.
    When you create an object, it has a retain count of 1. You create an object using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” (for example, alloc, newObject, or mutableCopy).
  • 向object发送retain消息,它的引用计数+1.
    When you send an object a retain message, its retain count is incremented by 1.
  • 向object发送release消息,引用计数-1.
    When you send an object a release message, its retain count is decremented by 1.

  • 向object发送autorelease消息,引用计数-1.当引用计数为0,object被释放 。
    When you send an object a autorelease message, its retain count is decremented by 1 at the end of the current autorelease pool block.If an object’s retain count is reduced to zero, it is deallocated.


trace_obj.png

ARC:自动引用计数

ARC模式下,引用计数的规则还起作用,只是编译器做retain,release,autorelease的工作。

内存管理和引用计数

WWDC Adopting Automatic Reference Counting

翻译

ARC基本规则

参考:

Transitioning to ARC Release Notes

规则总结

规则:

  • You cannot explicitly invoke dealloc, or implement or invoke retain, release, retainCount, or autorelease.

  • You cannot use NSAllocateObject or NSDeallocateObject.

  • You cannot use object pointers in C structures.

  • There is no casual casting between id and void *.

  • You cannot use NSAutoreleasePool objects.

  • You cannot use memory zones.

  • You cannot give an accessor a name that begins with new. This in turn means that you can’t, for example,

    // Won't work:
    @property NSString *newTitle;
    
    // Works:
    @property (getter=theNewTitle) NSString *newTitle;`

Is ARC slow?

It depends on what you’re measuring, but generally “no.” The compiler efficiently eliminates many extraneous retain/release calls and much effort has been invested in speeding up the Objective-C runtime in general. In particular, the common “return a retain/autoreleased object” pattern is much faster and does not actually put the object into the autorelease pool, when the caller of the method is ARC code.

引用类型:

ARC强引用和弱引用

Strong reference : 强引用指针增加对象引用计数。

Weak reference :弱引用指针不增加对象引用计数,对象被释放后,指针被置为nil

引用关键字:

__strong:_strong修饰符表示对对象的“强引用”。持有强引用的变量在超出其作用域时被废弃,随着强引用的失效,引用的对象会随之释放

__weak:

使用_strong修饰符的成员变量在持有对象时,很容易发生循环引用。

循环引用容易发生内存泄露。内存泄露就是应当废弃的对象在超出其生存周期后继续存在。

使用_weak修饰符可以避免循环引用。_weak修饰符还有另一有优点。在持有某对象的弱引用时,若该对象被废弃,则此弱引用将自动失效且处于nil被赋值的状态(空弱引用)。

__unsafe_unretained__

autoreleasing

使用关键字的格式,关键字在*号之后

MyClass * __weak myWeakReference;
MyClass * __unsafe_unretained myUnsafeReference;

循环引用

三种循环引用的模式:
  • 对象之间有“父子关系
  • Delegate模式
  • Blocks
解决方法:

ARC循环引用

管理Autorelease Pools

@autoreleasepool-内存的分配与释放

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-CJBFBEDI

使用autorelease pool 的场景:

  • 程序不基于 UI framework.
    If you are writing a program that is not based on a UI framework, such as a command-line tool.

  • 在循环中生成大量的临时变量,可以在for循环中用autorelease pool block。
    If you write a loop that creates many temporary objects.
    You may use an autorelease pool block inside the loop to dispose of those objects before the next iteration. Using an autorelease pool block in the loop helps to reduce the maximum memory footprint of the application.

  • Cocoa application中的每个线程维护自己的 autorelease pool block堆栈,所以开子线程需要生成自己的autorelease pool block.

    You must create your own autorelease pool block as soon as the thread begins executing; otherwise, your application will leak objects. (See Autorelease Pool Blocks and Threads for details.)

对象转换

在iOS世界,主要有两种对象:Objective-C 对象和 Core Foundation 对象0。Core Foundation 对象主要是有C语言实现的 Core Foundation Framework 的对象,其中也有对象引用计数的概念,只是不是 Cocoa Framework::Foundation Framework 的 retain/release,而是自身的 CFRetain/CFRelease 接口。

这两种对象间可以互相转换和操作,不使用ARC的时候,单纯的用C原因的类型转换,不需要消耗CPU的资源,所以叫做 Toll-Free bridged

对象转换

Transitioning to ARC Release Notes

  • __bridge` transfers a pointer between Objective-C and Core Foundation with no transfer of ownership.

  • __bridge_retained or CFBridgingRetain casts an Objective-C pointer to a Core Foundation pointer and also transfers ownership to you.

    You are responsible for calling CFRelease or a related function to relinquish ownership of the object.

  • __bridge_transfer or CFBridgingRelease moves a non-Objective-C pointer to Objective-C and also transfers ownership to ARC.

    ARC is responsible for relinquishing ownership of the object.


易飞扬,ARC系列

理解ARC强引用和弱引用指针类型

BeginARC

WWDC Adopting Automatic Reference Counting

内存管理和引用计数



相关文章
|
5月前
|
前端开发 开发工具 Swift
学习iOS开发的准备
准备学习iOS开发?确保有Mac和最新Xcode,先学好编程基础特别是Swift。利用Apple官方文档、在线课程和书籍作为资源。熟悉Xcode及Git,通过实践项目和开源代码积累经验。深研架构模式、核心框架和优化技巧。加入开发者社区,关注行业动态,持续学习。
53 1
|
7月前
|
Swift iOS开发 开发者
IOS开发基础知识:什么是 ARC(自动引用计数)?如何工作?
IOS开发基础知识:什么是 ARC(自动引用计数)?如何工作?
103 1
|
安全 前端开发 Android开发
鸿蒙开发|鸿蒙系统的介绍(为什么要学习鸿蒙开发|鸿蒙系统的官方定义|鸿蒙和安卓、ios的对比)
鸿蒙开发学习是一项探索性的工作,旨在开发一个全场景分布式操作系统,覆盖所有设备,让消费者能够更方便、更直观地使用各种设备。
726 6
鸿蒙开发|鸿蒙系统的介绍(为什么要学习鸿蒙开发|鸿蒙系统的官方定义|鸿蒙和安卓、ios的对比)
|
iOS开发
iOS UIKit Dynamics Demo 学习地址列表
iOS UIKit Dynamics Demo 学习地址列表
53 0
|
XML JSON 编解码
IM通讯协议专题学习(九):手把手教你如何在iOS上从零使用Protobuf
接上篇《金蝶随手记团队的Protobuf应用实践(原理篇)》,本文将以iOS端的Objective-C代码为例,图文并茂地向您菔救绾卧趇OS工程中快速使用Protobuf,希望对你有帮助。
181 0
IM通讯协议专题学习(九):手把手教你如何在iOS上从零使用Protobuf
|
iOS开发
iOS开发 - 写一个刷新的控件(未封装,适合新手学习,查看原理)
iOS开发 - 写一个刷新的控件(未封装,适合新手学习,查看原理)
153 0
iOS开发 - 写一个刷新的控件(未封装,适合新手学习,查看原理)
|
存储 Unix 编译器
|
存储 算法 iOS开发
|
存储 缓存 算法
iOS底层学习——对象初始化探索
iOS底层学习——对象初始化探索
|
物联网 Android开发 iOS开发
iOS开发 - 蓝牙学习的总结
iOS开发 - 蓝牙学习的总结
191 0