网站建设 首选百川互动网站备案服务号
,个人手机网站开发一,ARC的概念 ARC (Automatic Reference Counting,自动引用计数) 是苹果公司在其编程语言(如 Objective-C 和 Swift)中的内存管理机制。ARC 通过编译器插入的代码自动管理对象的内存生命周期,减少了手动内存管理的复杂…一,ARC的概念
ARC
(Automatic Reference Counting
,自动引用计数) 是苹果公司在其编程语言(如 Objective-C 和 Swift)中的内存管理机制。ARC 通过编译器插入的代码自动管理对象的内存生命周期,减少了手动内存管理的复杂性和错误。以下是 ARC 在编译期和运行期所做的工作:
二,编译期
1.插入引用计数操作
- 编译器会在适当的位置插入retain和release操作,retain用于增加对象的引用计数,release用于减少对象的引用计数。
- 编译器通过静态分析代码,确定在何处增加或减少对象的引用计数
// 示例代码 MyClass *obj = [[MyClass alloc] init]; // 引用计数为1 obj = nil; // 引用计数为0,触发dealloc释放内存
上面的代码,ARC会在编译时插入一下操作
MyClass *obj = [[MyClass alloc] init]; [obj retain]; // 增加引用计数 [obj release]; // 减少引用计数,当obj被赋值为null时
2,优化引用计数操作
编译器会尝试优化引用计数的操作,合并或消除不必要的retain和release调用,例如,编译器会合并多个相邻的retain和release操作减少性能开销
MyClass *obj1 = [[MyClass alloc] init]; MyClass *obj2 = obj1;
在这种情况下,编译器知道ob2是obj1的别名,不需要增加引用计数
3,插入autorelease池管理
- 对于某些方法(如工厂方法)返回的对象,编译器会插入autorelease调用,使对象在适当的时机释放。
+ (instancetype)myObject {return [[[self alloc] init] autorelease]; }
这里达到了延迟释放对象的效果,
autorelease
把对象添加到当前的auto release池
中,使得对象在某个时刻(通常是当前事件循环结束时)自动释放,而不是立即释放。这种机制允许开发者创建的对象在返回调用者后依旧有效,不会立即释放。4,生成dealloc方法
- 编译器会生成或补充类中的dealloc方法来释放实例变量或资源
- (void)dealloc {[_name release];[super dealloc]; }
5,内存管理规则检查
- 在编译期,ARC 会对代码进行检查,确保遵循内存管理规则。例如,编译器会检查对象的所有权转移是否正确,并发出警告或错误信息。
三,运行期
在运行期,ARC会根据编译器插入的代码来管理对象的生命周期。
1,管理引用计数
- 引用计数通过retain和release操作来管理。每当对象的引用计数变为零时,dealloc方法会被调用,释放对象的内存。
MyClass *obj = [[MyClass alloc] init]; // retainCount = 1 [obj retain]; // retainCount = 2 [obj release]; // retainCount = 1 [obj release]; // retainCount = 0, dealloc is called
2,处理autorelease池
- 每当一个对象呗autorelease时,他会被添加到当的auto release池中,池会在每个循环事件末尾被清空,从而释放池中的对象
@autoreleasepool {MyClass *obj = [[[MyClass alloc] init] autorelease];// obj will be released at the end of the autorelease pool block }
3,解决循环引用
- 使用weak来打破循环引用。弱引用不会增加对象的引用计数,当对象被释放时,弱应用会被自动值为nil.
@interface MyClass : NSObject @property (nonatomic, weak) id delegate; @end
4,动态内存管理
- ARC 运行期的内存管理是动态的,即在程序运行时根据实际情况管理对象的内存分配和释放
总结
- 对于
ARC
。编译器在代码里适当的地方自动插入retain
/release
完成内存管理(引用计数)。但ARC相对于MRC,又不是在编译时添加retain/release/autorelease这么简单。应该是编译期和运行期两部分共同帮助开发者管理内存。- 在编译期,
ARC
用的是更低层C接口实现的retain/release/autorelease
,并不通过OC
的消息转发机制,而是直接调用其底层C语言版本API,这样做的性能更好,因为保留及释放操作需要频繁的执行,直接调用其底层的函数能节省很多CPU周期。- ARC管理对象生命期的办法是:在合适的地方,插入“保留”及“释放”操作。在方法中创建的对象,在方法中自动插入
release
;类中的对象,在dealloc
方法中释放。- 通过retaincount的机制来决定对象是否需要被释放。每次
runloop
时,都会检查对象的retainCount,如果retaincount = 0时,说明该对象没有地方要继续使用了,可以释放掉了。补充:
对于__unsafe_unretained修饰符,__unsafe_unretained 和 __weak 相似,是一种弱引用关系。区别在于如果一个对象没有强指针引用,则 __unsafe_unretained 引用不会被置为 nil,而是会变成一个野指针。
那有了 __weak,为什么还有 __unsafe_unretained 呢?
__unsafe_unretained 主要是跟 C 语言代码相互。此外,__weak 会消耗一定的性能,使用 __weak 需要检查对象是否被释放,在追踪是否被释放的时候需要追踪一些信息,则使用 __unsafe_unretained 比 __weak 快,消耗 CPU 资源也比 __weak 少。
而且一个对象有大量的 __weak 引用对象的时候,当对象被释放,那么此时就要遍历 weak 表,把表里所有的指针置空,消耗 CPU 资源。
综上所述,当明确知道对象的生命期时,选择 __unsafe_unretained 会有一些性能提升。但是 __unsafe_unretained 也容易引发野指针问题。自动释放池
1,自动释放池底层怎么实现?
内存里面有栈,栈里面有自动释放池。自动释放池以栈的形式实现:当你创建一个新的自动释放池时,它将被添加到栈顶。当一个对象收到发送autorelease消息时,它被添加到当前线程的处于栈顶的自动释放池中,当自动释放池被回收时,它们从栈中被删除,并且会给池子里面所有的对象都会做一次release操作。
在iOS程序运行过程中,会创建无数个池子。这些池子都是以栈结构存在(先进后出)2,自动释放池作用
将对象与自动释放池建立关系,池子内调用 autorelease 方法,在自动释放池销毁时销毁对象,延迟 release 销毁时间3,苹果是如何实现 autoreleasepool 的?
autoreleasepool 以一个队列数组的形式实现,主要通过下列三个函数形成 objc_autoreleasepoolPush、objc_autoreleasepoolPop、objc_autorelease。
前两个函数执行 autorelease 的 push 和 pop 操作,销毁对象执行 release 操作。相关文章:
优购物官方网站app做旅游网站当地人服务赚钱吗 福州seo网站排名推广策划案怎么写 怎么自己做歌曲网站微信公众号推广2元一个 网站栏目标题网络营销推广与策划课后答案 海口公司网站建设网站方案制作的培训 给别人做网站怎么收取费用廊坊网站开发 网站口碑营销wordpress 不同侧边栏 论文中小企业的网站建设商城全网推广运营公司 网站开发要学多久科学数据分析网站html5 尧都网站建设项目外包app 山西房地产网站建设销售团队 订阅号可以建设微网站搬瓦工搭建wordpress 中煤建设协会网站网站关键词搜索排名怎么做 编写个人网站宝山区建设用地事务所网站 网站原则个人主页设计孙悟空示例 网站建设与管理模拟试卷一php网站开发语言的优点 用cms建网站容易吗网站首页图片轮转 浅谈天猫的电子商务网站建设乌克兰军事最新消息 贸易网站建设网电子商务网站建设开题报告 网站开发软件系统餐饮logo创意设计 微建站官网深圳建筑业网 遵义网站搭建公司哪家好20元备案域名 吴江网站设计wordpress 如何改中文 南京英文网站制作做网站jsp和php 投资者网站建设敖汉旗住房和城乡建设局网站 电商网站代码设计建设局发公告的网站 昌吉做网站兰州商城网站建 做茶叶网站wap建站系统 机构类网站有哪些医院网站建设的重要性 茂名免费自助建站模板域名备案