ARC 使用准则

Arc 到 Dia:从浏览器重构到 AI 原生产品的技术范式跃迁 通过创始人对 Arc 失败原因的坦诚反思,以及 Dia 技术路线的重构逻辑,我们可以清晰看到下一代 AI 浏览器的核心设计原则与技术挑战。正如创始人所言:“浏览器是互联网的入口,而 AI 将重塑它的每一次点击。Arc 团队在增长与留存数据持续走低的情况下,仍坚持“沉没成本”思维,延迟了产品转型。这种“不愿面对数据”的决策模式,本质上是。Arc 与 Dia 的迭代,标志着浏览器正在从“信息容器”进化为“智能代理平台”。在浏览器领域,Arc 与 Dia 的迭代不仅是一次产品形态的转变,更是一场关于。 阅读详情
28三/12 4

iPhone开发之深入浅出 (7) — ARC总结

  • 博主:易飞扬
  • 原文链接 : http://www.yifeiyang.net/development-of-the-iphone-simply-7/
  • 转载请保留上面文字。



    iPhone开发之深入浅出 (7) — ARC总结

    通过前面几篇文章的介绍,我想大家应该对ARC有了一个比较完整的理解。最后,我们来对ARC做一个总结,并把一些未涉及到的细节部分再深入讨论一下。

    内存管理基本原则

    内存管理的依循下面的基本原则
    • 自己生成的对象,那么既是其持有者
    • 不是自己生成的对象,也可成为其持有者(一个对象可以被多个人持有)
    • 如果不想持有对象的时候,必须释放其所有权
    • 不能释放已不再持有所有权的对象

      不管ARC有没有效,该原则始终存在。

    所有权关键字

    从代码上看,有ARC的代码和没有ARC的代码区别就在下面的几个关键字。

    类似 NSObject* 的对象类型,或者 id 类型1,当ARC有效的时候,根据具体情况,这些关键字必须要使用2。

    • __strong
    • __weak
    • __unsafe_unretained
    • __autoreleasing

      __strong是默认的修饰符。

      __weak修饰了一个自动nil的weak引用。

      __unsafe_unretained声明了一个不会自动nil的weak引用。当变量被释放,那么它就变成了一个野指针了。

      __autoreleasing 用来修饰一个声明为 (id *) 的函数的参数,当函数返回值时被释放。

    接下来,我们结合下面ARC的使用准则,来看看一些使用ARC后的技术细节。

    ARC使用准则

    为了比秒程序秒退的尴尬,ARC有效时,我们的代码必须遵循下面的准则。

    • 不能使用 retain/release/retainCount/autorelease
    • 不能使用 NSAllocateObject/NSDeallocateObject
    • 不能使用 NSZone
    • 不能明示调用dealloc
    • 内存管理相关的函数必须遵循命名规则
    • 使用@autoreleasepool代替NSAutoreleasePool
    • Objective-C 对象不能作为C语言结构体(struct/union)的成员
    • 【id】与【void*】之间需要明示cast

    建议使用Objective-C的class来管理数据格式,来代替C语言的struct。不能隐式转换 id 和 void *。

    让我们一个一个来分析
    不能使用 retain/release/retainCount/autorelease

    内存管理完全交给编译器去做,所以之前内存相关的函数(retain/release/retainCount/autorelease)不能出现在程序中。Apple的ARC文档中也有下面的说明。

    ARC 有效后,不需要再次使用retain 和 release

    如果我们在程序中使用这些函数,经得到类似下面的编译错误信息。

        error: ARC forbids explicit message send of ’release’
             [o release];
              ^ ~~~~~~~
    不能使用 NSAllocateObject/NSDeallocateObject

    生成并持有一个Objective-C对象的时候,往往像下面一样使用NSObject的alloc接口函数。

        id obj = [NSObject alloc];

    实际上,如果我们看了GNUstep 中关于 alloc 的代码就会明白,实际他是使用 NSAllocateObject 来生成并持有对象实例的。换言之,ARC有效的时候,NSAllocateObject函数的调用也是禁止的。如果使用,也会遇到下面的编译错误。

        error: ’NSAllocateObject’ is unavailable:
            not available in automatic reference counting mode

    同样,对象释放时使用的 NSDeallocateObject 函数也不能使用。

    不能使用 NSZone

    NSZone 是什么?NSZone 是为了防止内存碎片而导入的一项措施。Zone 是内存管理的基本单元,系统中管理复数的Zone。系统根据对象的使用目的,尺寸,分配其所属的Zone区域。以提高对象的访问效率,避免不必要的内存碎片。但是,现在的运行时系统(用编译开关 __OBJC2__ 指定的情况下)是不支持Zone概念的。所以,不管ARC是否有效,都不能使用 NSZone。

    不能明示调用dealloc

    不管是否使用ARC,当对象被释放的时候,对象的dealloc函数被调用(就像是C++中对象的析构函数)。在该函数中,需要做一些内存释放的动作。比如,当对象中使用了malloc分配的C语言内存空间,那么dealloc中就需要像下面一样处理内存的释放。

    1
    2
    3
    4
    - (void) dealloc
    {
        free(buffer_);
    }

    又或者是注册的delegate对象,观察者对象需要被删除的时候,也是在dealloc函数中动作。

    1
    2
    3
    4
    - (void) dealloc
    {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }

    如果在ARC无效的时候,我们还要像下面一样,调用父类对象的dealloc函数。

    1
    2
    3
    4
    - (void) dealloc
    {
        [super dealloc];
    }

    但是当ARC有效的时候,[super dealloc];的调用已经被编译器自动执行,已经不需要我们明示调用了。如果你在代码中还这样写,难免遇到下面的错误。

        error: ARC forbids explicit message send of ’dealloc’
             [super dealloc];
              ^ ~~~~~~~
    内存管理相关的函数必须遵循命名规则

    在iPhone开发之深入浅出 (3) — ARC之前世今生中,我们知道如果是 alloc/new/copy/mutableCopy/init 开头的函数,需要将对象所有权返回给调用端。这条规则不管ARC是否有效都应该被遵守。只是 init 开头的函数比较特殊,他只在ARC下有要求,而且异常苛刻。

    init 开始的函数只能返回id型,或者是该函数所属的类/父类的对象类型。基本上来说,init函数是针对alloc函数的返回值,做一些初始化处理,然后再将该对象返回。比如:

        id obj = [[NSObject alloc] init];

    再比如下面定义的函数就是不对的:

        - (void) initThisObject;

    需要是下面这样:

        - (id) initWithObject:(id)obj;

    另外,下面名为 initialize 的函数比较特殊,编译器将把它过滤掉,不按上面的规则处理。

    使用@autoreleasepool代替NSAutoreleasePool

    在ARC之下,已经不能在代码中使用 NSAutoreleasePool,我们之前写 main.m 文件的时候,往往像下面这样写。

    1
    2
    3
    4
    5
    6
        int main(int argc, char *argv[]) {
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
        int retVal = UIApplicationMain(argc, argv, nil, nil);
        [pool release];
        return retVal;
    }

    而当ARC有效后,我们需要用@autoreleasepool代替NSAutoreleasePool。

    1
    2
    3
    4
    5
    6
    int main(int argc, char *argv[])
    {
        @autoreleasepool {
            return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        }
    }

    当编译器看到 @autoreleasepool 定义的块后会自动生成 NSAutoreleasePool 对象,并将需要的对象放入 AutoReleasePool 中,当出方块的定义范围时,pool 中的对象将被释放。

    Objective-C 对象不能作为C语言结构体(struct/union)的成员

    当我们设置ARC有效,并在C语言的结构体中定义Objective-C的对象时,将出现类似下面的编译错误。

    1
    2
    3
    struct Data {
        NSMutableArray *array;
    };
        error: ARC forbids Objective-C objs in structs or unions
             NSMutableArray *array;
                             ^

    由于 ARC 是将内存管理的细节委托给编译器来做,所以说编译器必须要管理对象的生命周期。而LLVM 3.0中不存在对单纯C语言构造体成员的内存管理方法。如果单纯是栈对象,利用进出栈原理,可以简单地维护对象的生命周期;而结构体是不行的,简单地理解,结构体没有析构函数,编译器自身不能自动释放其内部的 Objective-C 对象。

    当我们必须在C语言的结构体中放入 Objective-C 对象的时候,可以使用 void* 转型,或者使用 __unsafe_unretained 关键字。比如下面:

    1
    2
    3
    struct Data {
        NSMutableArray __unsafe_unretained *array;
    };

    这样一来,该内存信息不在编译器内存管理对象内,仅仅是使用而已,没有对象的持有权。当然,对象所有权的持有者需要明确的管理他与该结构体的交互,不要引起不必要的错误3。

    【id】与【void*】之间需要明示cast

    ARC 有效的时候,由于编译器帮我们做了内存管理的工作,所以我们不需要太担心。但是当与 ARC 管理以外的对象类型交互的时候,就需要特殊的转型关键字,来决定所有权的归属问题。

    主要的转型关键字是:

    关键字 解释
    __bridge 单纯的类型转换,没有进行所有权的转移
    __bridge_retained 类型转换是伴随所有权传递,转换前后变量都持有对象的所有权
    __bridge_transfer 类型转换伴随所有权转移,被转换变量将失去对象的所有权

    当我们在 Core Foundation 对象类型与 Objective-C 对象类型之间切换的时候,需要把握下面的因素:

    • 明确被转换类型是否是 ARC 管理的对象
      • Core Foundation 对象类型不在 ARC 管理范畴内
      • Cocoa Framework::Foundation 对象类型(即一般使用到的Objectie-C对象类型)在 ARC 的管理范畴内
    • 如果不在 ARC 管理范畴内的对象,那么要清楚 release 的责任应该是谁
    • 各种对象的生命周期是怎样的

    题外话

    Xcode 4.3带来的变化

    最近随着 iOS 5.1 的推出,Xcode也推出了4.3版本。在该版本下,ARC 有效时的属性(@property) 定义的时候,如果不明确指定所有权关键字,那么缺省的就是 strong。而在 Xcode4.2 中,即使 strong 也要显示指定。

    在 Xcode4.2 的时候,针对下面的代码,

    1
    2
    3
    4
    5
    6
    7
    // ARC 无效
    @property (nonatomic, retain) NSString *string;
    
    // --->
    
    // ARC 有效
    @property (nonatomic, strong) NSString *string;

    而在 Xcode 4.3 中,我们可以这么做,

    1
    2
    3
    4
    5
    6
    7
    // ARC 无效
    @property (nonatomic, retain) NSString *string;
    
    // --->
    
    // ARC 有效
    @property (nonatomic) NSString *string;
    ARC 代码自动变换

    另外,Xcode 4.2开始,增加了旧代码向 ARC 代码自动转换的功能。有兴趣的朋友可以试试。位置是:

    Edit->Refactor->Convert to Objective-C ARC…

    为什么iOS中没有GC

    我们已经知道ARC并不是GC(垃圾回收)了,那么,为什么iOS中不支持该机能呢?还特意搞出个ARC来。以下是我的分析:

    • 消耗CPU时间的处理尽量避免,以节约电池电量
    • GC执行的后,会停掉运行时库;这是最大的心结
    • 嵌入式设备本身内存就不是很大,如果GC不停的在后台运行,执行的频率会很高,严重影响性能
      • UI动画处理是iOS的一大卖点,而有了GC后可能会引起不必要的性能损失

    1. 关于Objective-C对象的解释,可以参考iPhone开发入门(7)— 从C/C++语言到Objective-C语言。

    2. 当然,如果你不写,编译器会用缺省的值代替。具体见iPhone开发之深入浅出 (3) — ARC之前世今生中的描述。

    3. 关于这一点,可以参考iPhone开发之深入浅出 (1) — ARC是什么 一文,明白为什么 __unsafe_unretained 是危险的。

智能车PCB设计避坑指南:嘉立创审核规则与立创EDA、AD、KiCad选型对比 PCB设计是硬件工程中绕不开的核心环节,其可制造性直接决定产品从图纸到实物的转化质量。在智能车竞赛等复杂电子系统开发中,设计规则检查(DRC)与可制造性设计(DFM)是保障板卡稳定运行的关键前提。理解工厂端的工艺边界,如最小线宽线距、过孔孔径、丝印与阻焊层规范,能显著降低打样驳回率,提升研发迭代效率。针对不同团队的技术基础与资源条件,选择合适的EDA工具链——从生态无缝集成的立创EDA,到老牌高效的Altium Designer,再到开源跨平台的KiCad——各有适用场景。掌握布局、布线、铜皮载流、电源完整 阅读详情

相关推荐

OBD诊断协议:OBDⅡ (SAE J1979) 和 OBDonUDS (SAE J1979-2) 和ZEV OBD技术架构的详细对比

摘要:文章对比了2025年最新OBD技术标准(SAEJ1979系列)的三大架构:传统OBD-II(已淘汰)、OBDonUDS(燃油/混动车)和ZEVOBD(新能源车)。核心发现:1)OBDonUDS与ZEVOBD共享UDS协议栈和DoIP通信标准,仅应用层数据(DID/DTC)不同;2)物理层统一为CAN+以太网,支持远程诊断和OTA;3)诊断工具需同时兼容J1979-2/3数据库。技术演进呈现"协议统一化、数据专用化"趋势,2027年后所有新车将强制采用新标准。

m0_56482679的博客 2393

iPhone开发之深入浅出 (7) — ARC总结

  通过前面几篇文章的介绍,我想大家应该对ARC有了一个比较完整的理解。最后,我们来对ARC做一个总结,并把一些未涉及到的细节部分再深入讨论一下。 内存管理基本原则 内存管理的依循下面的基本原则 自己生成的对象,那么既是其持有者 不是自己生成的对象,也可成为其持有者(一个对象可以被多个人持有) 如果不想持有对象的时候,必须释放其所有权 不能释放已不再持有所有权的对象 ...

SouthKing 271

从农田到城市:如何利用NDVI和缨帽变换提升遥感图像分类精度?

本文深入探讨了如何利用NDVI(归一化差值植被指数)和缨帽变换(Tasseled Cap Transformation)两大关键技术,有效提升从农田到城市等复杂场景的遥感图像分类精度。文章通过剖析地物光谱特征,对比了原始波段与衍生特征的优劣,并提供了在ENVI、ArcGIS及Python环境中的具体操作指南与实战策略,旨在帮助从业者构建更鲁棒的特征工程流程,从而解决地物混淆、边界模糊等常见分类难题。

redis7keeper的博客 867

c语言arc函数有几个参数,ARC规则

概要ARC即为“自动引用计数”,自动的帮我们处理引用计数的相关部分。在编译单位上,我们可以设置ARC是有效或者无效,甚至可以对每个文件选择是否使用ARC。一个应用程序中可以混合ARC有效或者ARC无效的二进制形式哦。内存管理的思考方式上文中提到的内存管理的四种思考方式在ARC有效时也是可行的。引用计数式内存管理的思考方式就是思考ARC所引起的变化*自己生成的对象,自己持有*非自己生成的对象,自己也...

weixin_39777875的博客 1094

PCB阻焊工艺全解析:从油墨选择到显影测试的完整指南

本文深入解析PCB阻焊工艺全流程,从材料科学角度对比液态光成像(LPI)油墨、干膜阻焊等核心材料特性,系统阐述前处理、涂覆、预烤曝光、显影固化等关键步骤的工艺要点与参数控制。重点探讨了如何通过优化油墨选择与工艺参数,解决常见缺陷,提升PCB的可靠性、美观度及可制造性,为工程师提供从理论到产线实战的完整指南。

s3t4u的博客 553

别再纠结选哪个向量库了!我用Spring AI + Redis Stack 7.2,5分钟搞定企业知识库RAG原型

本文介绍了如何利用Spring AI和Redis Stack 7.2快速构建企业级RAG应用,解决向量数据库选型难题。Redis Stack 7.2集成了RediSearch模块,支持向量相似性搜索,具备高性能、低成本、零学习成本等优势,特别适合中小团队快速搭建知识库系统。通过实战代码示例,展示了从环境准备到核心功能实现的完整流程。

weixin_29061041的博客 272

Python与HTML倾情打造情人节示爱网站:愿天下有情人终成眷属!

陪伴是最长情的告白 世人醉,醉生梦死一世情;世人痴,痴心不悔三生爱。在2021年2月14日到来之际,Python与HTML携手,运用独家浪漫方法为您倾情打造情人节示爱网站;在这里,有各种功能、各种方法,为你和Ta留下最珍贵的回忆,并记录你们的爱情...... 目录 1 故事开篇 2 计划实施 2.1 Python 2.1.1 环境介绍 2.1.2 tornado实施步骤 2.1.3 Python完整代码文件交付 2.2 HTML 2.2.1 HTML的一个小惊喜 2.2.2...

闭关修炼——暂退 2万+

V93000 SmarTest 8入门:从零搭建你的第一个半导体测试程序

半导体测试是芯片从设计走向量产的关键环节,而ATE(自动化测试设备)正是支撑这一环节的核心工具。理解ATE测试程序开发的基本原理,不仅需要掌握测试机台的硬件架构,还要熟悉其软件环境中的管脚映射、电平时序、测试流程等底层逻辑。V93000作为爱德万的主力平台,其SmarTest 8环境通过对象化与流程化设计,将复杂的芯片测试任务拆解为可配置、可复用的模块,极大提升了并行测试效率与调试的便利性。无论是数字逻辑芯片的功能验证,还是模拟混合信号器件的参数测量,掌握SmarTest 8的核心操作都能帮助你快速搭建出可

weixin_31476015的博客 244

关于QTP

关于QTP,我也才接触,只是上来记录一下安装过程,免得以后忘记,又要查一堆资料。 简单介绍一下QTP: QTP的基本功能包括2个部分:一部分是提供给初级用户使用的关键字视图;另一部分是提供给熟悉VBScript脚本编写的自动化测试工程师使用的专家视图。但并没有严格的区分,在实际的自动化测试项目中完全可以两者结合着使用。 使用QTP进行自动化测试的基本过程与使...

dhtlvr31595的博客 236

一文了解向量数据库在RAG中扮演的角色

向量数据库:AI新纪元的基石。探索如何通过这一创新技术优化RAG,提高语言模型的信息处理能力

2401_82452722的博客 2452

Arduino ESP32S3开发环境搭建 ------ 在线下载安装包Failed解决方案

本文介绍了Arduino ESP32 S3开发环境搭建的离线解决方案。

张一西的博客 1018

c语言arc函数带几个参数,ARC的使用简要总结

.h文件中:1,@property (strong,nonatomic)中属性的定义主要是类对外的接口,将retain,copy等变为strong。2,私有变量.m文件中的类扩展定义的私有属性变量,即@interface class (){@property()nsarray *array;}现在直接在类实现中@implementation class{ nsarray *array;}即可---...

weixin_32389225的博客 3086

【好玩的游戏项目】使用Docker快速部署属于你的RPG网页小游戏

【好玩的游戏项目】使用Docker快速部署属于你的RPG网页小游戏

jks212454的博客 5577

ARC总结

通过前面几篇文章的介绍,我想大家应该对ARC有了一个比较完整的理解。最后,我们来对ARC做一个总结,并把一些未涉及到的细节部分再深入讨论一下。 内存管理基本原则 内存管理的依循下面的基本原则 自己生成的对象,那么既是其持有者  不是自己生成的对象,也可成为其持有者(一个对象可以被多个人持有)  如果不想持有对象的时候,必须释放其所有权  不能释放已不再持有所有权

afdl9999的专栏 552

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

IOS ARC 使用

转自:http://www.yifeiyang.net/development-of-the-iphone-simply-7/

martin_liang的专栏 550

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

iOS开发之深入浅出 (7) — ARC总结

通过前面几篇文章的介绍,我想大家应该对ARC有了一个比较完整的理解。最后,我们来对ARC做一个总结,并把一些未涉及到的细节部分再深入讨论一下。 内存管理基本原则 内存管理的依循下面的基本原则 自己生成的对象,那么既是其持有者不是自己生成的对象,也可成为其持有者(一个对象可以被多个人持有)如果不想持有对象的时候,必须释放其所有权不能释放已不再持有所有权的对象不管ARC有没有效,

LDM 605

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

ARC的理解及应用

一,ARC的概念和原理: 1,指针分类:     (1)强指针:默认的情况下,所有的指针都是强指针,关键字strong;     (2)弱指针:_ _weak关键字修饰的指针; 2,什么是ARC:     Automatic Reference Counting,自动引用计数,即ARC;     ARC是新的LLVM 3.0编译器的一项特性; 3,ARC原理:     ARC是Objectiv

克莱斯勒的博客 1477

ARC机制介绍及使用

ARC简介 ARC机制判断 ARC下对象内存管理 ARC下property参数 ARC的兼容和转换 总结ARC简介 1.指针分类 1)强指针:__strong关键字修饰的指针。默认情况下,所有指针都是强指针,2)弱指针:__weak关键字修饰的指针 声明一个弱指针:__weak Person * p;/

庐山烟雨浙江潮 782

ARC(七):ARC总结

通过前面几篇文章的介绍,我想大家应该对ARC有了一个比较完整的理解。最后,我们来对ARC做一个总结,并把一些未涉及到的细节部分再深入讨论一下。 内存管理基本原则 内存管理的依循下面的基本原则 自己生成的对象,那么既是其持有者 不是自己生成的对象,也可成为其持有者(一个对象可以被多个人持有) 如果不想持有对象的时候,必须释放其所有权 不能释放已不再持有所有权的对象

攀石的专栏 499

[转]ARC深入浅出

ARC可谓iOS开发中一大利器,内存管理的大部份问题都能交由系统自动处理了,不过一些不太明显的小坑也需我们多加注意,不然用户在使用中出现闪退,那用户体验就差多了。最近看了@易飞扬 先生一系列关于ARC的博文,觉得非常详细易懂,可惜需要翻墙才能看到,所以转载到这里,同时对原文内容进行了一些小修改,再次感谢易先生的分享 :P TL;DR 内存管理依循下面的基本原则: 自己生成的对象,那么即是

handsome113的专栏 1218

OC内存管理ARC

1.什么是ARC Automatic Reference Counting,自动引用计数,即ARC,在WWDC2011和iOS5引入的最大的变革和最激动人心的变化。ARC是新的LLVM 3.0编译器的一项特性,使用ARC,可以说一 举解决了广大iOS开发者所憎恨的手动内存管理的麻烦。 手动管理内存, 可以简称MRC (Manual Reference Counting) 在工程...

张聪的博客 424

iPhone开发之深入浅出 (3) — ARC之前世今生

19二/126 iPhone开发之深入浅出 (3) — ARC之前世今生 博主:易飞扬 原文链接 : http://www.yifeiyang.net/development-of-the-iphone-simply-3/ 转载请保留上面文字。  Objective-C 内存管理  基本原则  编程准则  ARC 诞生

u011025344的专栏 408

OC ARC机制

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------  ARC  就是自动引用计数, OC中引入的自动引用计数概念和java中的垃圾回收机制不同, java中的垃圾回收是在程序运行时进行判断, 如果某些对象不再需要了,则对其进行释放.  而ARC是一种编译器特性, 是在编译代码中, 合适的位置插入 release方法. 也就不太需要我

伟的专栏 648
上一篇: Mac 下Andriod 开发环境搭建
下一篇: UIView 用户事件相应总结1
皓浩
博客等级 码龄18年 157粉丝 121原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值