黑箱中的 retain 和 release

【信息科学与工程学】【管理科学】第五十一篇 舆论营销工程驱动人性综合模型框架03 ——企业内部舆论工程01 高管合法性(P-101)↓ 提供压力与合法性中层传导(P-202) → 合谋时触发镇压(S-202)↓ 输出规训要求员工规训(C-305) → 高异议时触发镇压(S-305)↓ 产生抵抗信号抵抗行为(R系列) → 触发相应镇压(S系列)↓ 增加系统风险风险累积(E-501) → 预警并调节所有控制模型。 阅读详情



> 由于 Objective-C 中的内存管理是一个比较大的话题,所以会分为两篇文章来对内存管理中的一些机制进行剖析,一部分分析自动释放池以及 `autorelease` 方法,另一部分分析 `retain`、`release` 方法的实现以及自动引用计数。


+ [自动释放池的前世今生](https://github.com/Draveness/iOS-Source-Code-Analyze/blob/master/objc/自动释放池的前世今生.md)

+ [黑箱中的 retain 和 release](https://github.com/Draveness/iOS-Source-Code-Analyze/blob/master/objc/黑箱中的%20retain%20和%20release.md)


## 写在前面


在接口设计时,我们经常要考虑某些意义上的平衡。在内存管理中也是这样,Objective-C 同时为我们提供了增加引用计数的 `retain` 和减少引用计数的 `release` 方法。


这篇文章会在源代码层面介绍 Objective-C 中 `retain` 和 `release` 的实现,它们是如何达到平衡的。


## 从 retain 开始


如今我们已经进入了全面使用 ARC 的时代,几年前还经常使用的 `retain` 和 `release` 方法已经很难出现于我们的视野中了,绝大多数内存管理的实现细节都由编译器代劳。


在这里,我们还要从 `retain` 方法开始,对内存管理的实现细节一探究竟。


下面是 `retain` 方法的调用栈:


```objectivec

- [NSObject retain]

└── id objc_object::rootRetain()

    └── id objc_object::rootRetain(bool tryRetain, bool handleOverflow)

        ├── uintptr_t LoadExclusive(uintptr_t *src)

        ├── uintptr_t addc(uintptr_t lhs, uintptr_t rhs, uintptr_t carryin, uintptr_t *carryout)

        ├── uintptr_t bits

        │   └── uintptr_t has_sidetable_rc  

        ├── bool StoreExclusive(uintptr_t *dst, uintptr_t oldvalue, uintptr_t value)

        └── bool objc_object::sidetable_addExtraRC_nolock(size_t delta_rc)                

            └── uintptr_t addc(uintptr_t lhs, uintptr_t rhs, uintptr_t carryin, uintptr_t *carryout)

```


调用栈中的前两个方法的实现直接调用了下一个方法:


```objectivec

- (id)retain {

    return ((id)self)->rootRetain();

}


id objc_object::rootRetain() {

    return rootRetain(false, false);

}

```


而 `id objc_object::rootRetain(bool tryRetain, bool handleOverflow)` 方法是调用栈中最重要的方法,其原理就是将 `isa` 结构体中的 `extra_rc` 的值加一。


`extra_rc` 就是用于保存自动引用计数的标志位,下面就是 `isa` 结构体中的结构:


![objc-rr-isa-struct](../images/objc-rr-isa-struct.png)


接下来我们会分三种情况对 `rootRetain` 进行分析。


### 正常的 rootRetain


这是简化后的 `rootRetain` 方法的实现,其中只有处理一般情况的代码:


```objectivec

id objc_object::rootRetain(bool tryRetain, bool handleOverflow) {

    isa_t oldisa;

    isa_t newisa;


    do {

        oldisa = LoadExclusive(&isa.bits);

        newisa = oldisa;


        uintptr_t carry;

        newisa.bits = addc(newisa.bits, RC_ONE, 0, &carry);

    } while (!StoreExclusive(&isa.bits, oldisa.bits, newisa.bits));


    return (id)this;

}

```


> 在这里我们假设的条件是 `isa` 中的 `extra_rc` 的位数足以存储 `retainCount`。


1. 使用 `LoadExclusive` 加载 `isa` 的值

2. 调用 `addc(newisa.bits, RC_ONE, 0, &carry)` 方法将 `isa` 的值加一

3. 调用 `StoreExclusive(&isa.bits, oldisa.bits, newisa.bits)` 更新 `isa` 的值

4. 返回当前对象


### 有进位版本的 rootRetain


在这里调用 `addc` 方法为 `extra_rc` 加一时,8 位的 `extra_rc` 可能不足以保存引用计数。


```objectivec

id objc_object::rootRetain(bool tryRetain, bool handleOverflow) {

    transcribeToSideTable = false;

    isa_t oldisa = LoadExclusive(&isa.bits);

    isa_t newisa = oldisa;


    uintptr_t carry;

    newisa.bits = addc(newisa.bits, RC_ONE, 0, &carry);


    if (carry && !handleOverflow)

        return rootRetain_overflow(tryRetain);

}

```


> `extra_rc` 不足以保存引用计数,并且 `handleOverflow = false`。


当方法传入的 `handleOverflow = false` 时(这也是通常情况),我们会调用 `rootRetain_overflow` 方法:


```objectivec

id objc_object::rootRetain_overflow(bool tryRetain) {

    return rootRetain(tryRetain, true);

}

```


这个方法其实就是重新执行 `rootRetain` 方法,并传入 `handleOverflow = true`。


### 有进位版本的 rootRetain(处理溢出)


当传入的 `handleOverflow = true` 时,我们就会在 `rootRetain` 方法中处理引用计数的溢出。


```objectivec

id objc_object::rootRetain(bool tryRetain, bool handleOverflow) {

    bool sideTableLocked = false;


    isa_t oldisa;

    isa_t newisa;


    do {

        oldisa = LoadExclusive(&isa.bits);

        newisa = oldisa;

        uintptr_t carry;

        newisa.bits = addc(newisa.bits, RC_ONE, 0, &carry);


        if (carry) {

            newisa.extra_rc = RC_HALF;

            newisa.has_sidetable_rc = true;

        }

    } while (!StoreExclusive(&isa.bits, oldisa.bits, newisa.bits));


    sidetable_addExtraRC_nolock(RC_HALF);


    return (id)this;

}

```


当调用这个方法,并且 `handleOverflow = true` 时,我们就可以确定 `carry` 一定是存在的了,


因为 `extra_rc` 已经溢出了,所以要更新它的值为 `RC_HALF`:


```c

#define RC_HALF (1ULL<<7)

```


> `extra_rc` 总共为 8 位,`RC_HALF = 0b10000000`。


然后设置 `has_sidetable_rc` 为真,存储新的 `isa` 的值之后,调用 `sidetable_addExtraRC_nolock` 方法。


```objectivec

bool objc_object::sidetable_addExtraRC_nolock(size_t delta_rc) {

    SideTable& table = SideTables()[this];


    size_t& refcntStorage = table.refcnts[this];

    size_t oldRefcnt = refcntStorage;


    if (oldRefcnt & SIDE_TABLE_RC_PINNED) return true;


    uintptr_t carry;

    size_t newRefcnt = 

        addc(oldRefcnt, delta_rc << SIDE_TABLE_RC_SHIFT, 0, &carry);

    if (carry) {

        refcntStorage = SIDE_TABLE_RC_PINNED | (oldRefcnt & SIDE_TABLE_FLAG_MASK);

        return true;

    } else {

        refcntStorage = newRefcnt;

        return false;

    }

}

```


这里我们将溢出的一位 `RC_HALF` 添加到 `oldRefcnt` 中,其中的各种 `SIDE_TABLE` 宏定义如下:


```objectivec

#define SIDE_TABLE_WEAKLY_REFERENCED (1UL<<0)

#define SIDE_TABLE_DEALLOCATING      (1UL<<1)

#define SIDE_TABLE_RC_ONE            (1UL<<2)

#define SIDE_TABLE_RC_PINNED         (1UL<<(WORD_BITS-1))


#define SIDE_TABLE_RC_SHIFT 2

#define SIDE_TABLE_FLAG_MASK (SIDE_TABLE_RC_ONE-1)

```


因为 `refcnts` 中的 64 为的最低两位是有意义的标志位,所以在使用 `addc` 时要将 `delta_rc` 左移两位,获得一个新的引用计数 `newRefcnt`。


如果这时出现了溢出,那么就会撤销这次的行为。否则,会将新的引用计数存储到 `refcntStorage` 指针中。


----


也就是说,在 iOS 的内存管理中,我们使用了 `isa` 结构体中的 `extra_rc` 和 `SideTable` 来存储某个对象的自动引用计数。


更重要的是,**如果自动引用计数为 1,`extra_rc` 实际上为 0**,因为它保存的是额外的引用计数,我们通过这个行为能够减少很多不必要的函数调用。


到目前为止,我们已经从头梳理了 `retain` 方法的调用栈及其实现。下面要介绍的是在内存管理中,我们是如何使用 `release` 方法平衡这个方法的。


## 以 release 结束


与 release 方法相似,我们看一下这个方法简化后的调用栈:


```objectivec

- [NSObject release]

└── id objc_object::rootRelease()

    └── id objc_object::rootRetain(bool performDealloc, bool handleUnderflow)

```


前面的两个方法的实现和 `retain` 中的相差无几,这里就直接跳过了。


同样,在分析 `release` 方法时,我们也根据上下文的不同,将 `release` 方法的实现拆分为三部分,说明它到底是如何调用的。


### 正常的 release


这一个版本的方法调用可以说是最简版本的方法调用了:


```objectivec

bool objc_object::rootRelease(bool performDealloc, bool handleUnderflow) {

    isa_t oldisa;

    isa_t newisa;


    do {

        oldisa = LoadExclusive(&isa.bits);

        newisa = oldisa;


        uintptr_t carry;

        newisa.bits = subc(newisa.bits, RC_ONE, 0, &carry);

    } while (!StoreReleaseExclusive(&isa.bits, oldisa.bits, newisa.bits));


    return false;

}

```


1. 使用 `LoadExclusive` 获取 `isa` 内容

2. 将 `isa` 中的引用计数减一

3. 调用 `StoreReleaseExclusive` 方法保存新的 `isa`


### 从 SideTable 借位


接下来,我们就要看两种相对比较复杂的情况了,首先是从 `SideTable` 借位的版本:


```objectivec

bool objc_object::rootRelease(bool performDealloc, bool handleUnderflow) {

    isa_t oldisa;

    isa_t newisa;


    do {

        oldisa = LoadExclusive(&isa.bits);

        newisa = oldisa;


        uintptr_t carry;

        newisa.bits = subc(newisa.bits, RC_ONE, 0, &carry);

        if (carry) goto underflow;

    } while (!StoreReleaseExclusive(&isa.bits, oldisa.bits, newisa.bits));

    

    ...


 underflow:

    newisa = oldisa;


    if (newisa.has_sidetable_rc) {

        if (!handleUnderflow) {

            return rootRelease_underflow(performDealloc);

        }


        size_t borrowed = sidetable_subExtraRC_nolock(RC_HALF);


        if (borrowed > 0) {

            newisa.extra_rc = borrowed - 1;

            bool stored = StoreExclusive(&isa.bits, oldisa.bits, newisa.bits);


            return false;

        } 

    }

}

```


> 这里省去了使用锁来**防止竞争条件**以及**调用 `StoreExclusive` 失败后恢复现场**的代码。

> 我们会默认这里存在 `SideTable`,也就是 `has_sidetable_rc = true`。


你可以看到,这里也有一个 `handleUnderflow`,与 retain 中的相同,如果发生了 `underflow`,会重新调用该 `rootRelease` 方法,并传入 `handleUnderflow = true`。


在调用 `sidetable_subExtraRC_nolock` 成功借位之后,我们会重新设置 `newisa` 的值 `newisa.extra_rc = borrowed - 1` 并更新 `isa`。


### release 中调用 dealloc


如果在 `SideTable` 中也没有获取到借位的话,就说明没有任何的变量引用了当前对象(即 `retainCount = 0`),就需要向它发送 `dealloc` 消息了。


```objectivec

bool objc_object::rootRelease(bool performDealloc, bool handleUnderflow) {

    isa_t oldisa;

    isa_t newisa;


 retry:

    do {

        oldisa = LoadExclusive(&isa.bits);

        newisa = oldisa;


        uintptr_t carry;

        newisa.bits = subc(newisa.bits, RC_ONE, 0, &carry);

        if (carry) goto underflow;

    } while (!StoreReleaseExclusive(&isa.bits, oldisa.bits, newisa.bits));


    ...


 underflow:

    newisa = oldisa;


    if (newisa.deallocating) {

        return overrelease_error();

    }

    newisa.deallocating = true;

    StoreExclusive(&isa.bits, oldisa.bits, newisa.bits);


    if (performDealloc) {

        ((void(*)(objc_object *, SEL))objc_msgSend)(this, SEL_dealloc);

    }

    return true;

}

```


上述代码会直接调用 `objc_msgSend` 向当前对象发送 `dealloc` 消息。


不过为了确保消息只会发送一次,我们使用 `deallocating` 标记位。


## 获取自动引用计数


在文章的最结尾,笔者想要介绍一下 `retainCount` 的值是怎么计算的,我们直接来看 `retainCount` 方法的实现:


```objectivec

- (NSUInteger)retainCount {

    return ((id)self)->rootRetainCount();

}


inline uintptr_t objc_object::rootRetainCount() {

    isa_t bits = LoadExclusive(&isa.bits);

    uintptr_t rc = 1 + bits.extra_rc;

    if (bits.has_sidetable_rc) {

        rc += sidetable_getExtraRC_nolock();

    }

    return rc;

}

```


 根据方法的实现,retainCount 有三部分组成:

 

 + 1

 + `extra_rc` 中存储的值

 + `sidetable_getExtraRC_nolock` 返回的值


这也就证明了我们之前得到的结论。


## 小结


我们在这篇文章中已经介绍了 `retain` 和 `release` 这一对用于内存管理的方法是如何实现的,这里总结一下文章一下比较重要的问题。


+ `extra_rc` 只会保存额外的自动引用计数,对象实际的引用计数会在这个基础上 +1

+ Objective-C 使用 `isa` 中的 `extra_rc` 和 `SideTable` 来存储对象的引用计数

+ 在对象的引用计数归零时,会调用 `dealloc` 方法回收对象


有关于自动释放池实现的介绍,可以看[自动释放池的前世今生](https://github.com/Draveness/iOS-Source-Code-Analyze/blob/master/objc/自动释放池的前世今生.md)。


> Follow: [Draveness · Github](https://github.com/Draveness)



利用MATLAB 4f光学系统,在Python中进行弗劳恩霍夫衍射和傅里叶面滤波——用镜头模拟光学图像处理。.zip 1.版本:matlab2014a/2019b/2024b 2.附赠案例数据可直接运行。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 立即下载

相关推荐

工业互联网工控安全与工业质检AI大模型建设方案.pptx

工业互联网工控安全与工业质检AI大模型建设方案.pptx

【木头Cocos2d-x 037】retain和release倒底怎么玩?

retain和release倒底怎么玩?   呼呼,好久没有发布教程了(小若:难得清静了,你为毛又出来吓人= =),其实最近木头我在准备出版书籍的事情。但是貌似不太顺利,果然我还是积累不够,写书的过程压力好大,感觉写不出有趣的文字出来(小若:嗷、、、)。果然还是在博客写自由一些?嘿嘿~ 最近以及最不是很近(小若:书里一定不能出现这些错误的语句,所以你才写不出来吧= =),不少朋友对ret

笨木头 2万+

通信行业CentOS 7内核网络栈优化:高并发连接下UDP/TCP性能调优与系统资源管理

内容概要:本文聚焦于CentOS 7系统在通信行业高并发场景下的性能调优实践,重点围绕内核网络栈优化展开,涵盖UDP/TCP缓冲区调整、文件句柄与连接跟踪表扩容、TIME_WAIT状态复用、软中断分布优化及tuned工具的自动化调优。通过具体配置参数和实际案例(如VoIP软交换系统)深入解析各项调优措施的设计原理与实施效果,有效解决高CPS下丢包、连接失败等问题,并展望了向云化、eBPF等动态智能调优方向的发展趋势。; 适合人群:从事通信系统运维、网络开发或Linux系统性能优化的技术人员,具备一定操作系统和网络基础知识,工作经验1年以上的中初级工程师。; 使用场景及目标:①应用于软交换、媒体网关、信令网关等高并发通信设备的系统调优;②解决UDP丢包、conntrack表满、TCP连接队列溢出等典型性能瓶颈;③提升系统在小包高频、低时延要求场景下的稳定性和吞吐能力。; 阅读建议:建议结合实际生产环境或测试平台同步验证文中配置,重点关注参数背后的物理意义(如BDP、softirq、conntrack机制),并配合ss、conntrack、dmesg等命令进行调优前后对比分析,确保安全可控地实施变更。

retain和release

如果继承自 cc.Class或其子类,那么jsb就引用了c++的内存。 这样就可能用到 retain和release 如果不调用c++层的方法,那么没必要用retain和release 因为c++层的内存和js层是独立管理的。 比如 ClassA = cc.Layer.extend(...); 如果不调用和c++层的layer相关的函数或属性【比如addChild

xiuzhentianting的博客 530

2024 《计算机网络》实验教学指导书.doc

2024 《计算机网络》实验教学指导书.doc

不平衡电网下自抗扰顺序模型预测PWM整流器控制仿真模型(Simulink仿真实现)

内容概要:本文围绕面向城市空中交通的多无人机路径规划问题展开研究,提出了一套融合全局规划、动态避障与局部协同调整的综合路径规划方法。研究内容涵盖基于改进RRT算法与图论的全局路径规划、基于动态风险场和动态窗口法(DWA)的模型预测控制实现动态避障,以及基于分布式协同控制的多无人机局部路径协同策略。通过Matlab平台构建仿真环境,在多种典型城市交通场景下对所提方法进行了系统性验证,结果表明该方法在路径安全性、编队稳定性与任务效率方面表现优异。文章还深入探讨了算法的创新点与未来研究方向,为复杂城市环境下多无人机系统的自主协同提供了理论支撑与技术路径。; 适合人群:具备自动化、控制理论、计算机科学或相关领域基础知识,从事无人机系统、智能交通、路径规划、多智能体协同控制等方向研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①为城市空中交通系统中的多无人机安全、高效飞行提供可靠的路径规划解决方案;②支持在复杂、动态的城市场景中开展无人机自主导航、编队飞行与协同控制的技术研究与仿真验证。; 阅读建议:建议结合提供的Matlab代码进行实践操作,重点关注算法的具体实现细节、参数配置对性能的影响以及不同仿真场景下的实验设计,以深入理解各模块的集成逻辑与实际应用效果。

retain和release实现探究

前面一篇文章,我们讲到了系统为了优化数字字符串等类型的数据存储新增了一种NSTaggedPointer类型,同时我们还发现,isa指针在经过优化后,提供了19个bit位用来存储引用计数的个数。但是如果超出了这个限制呢? 引用计数 其实在绝大多数情况下,仅用优化的isa_t来记录对象的引用计数就足够了,但是当对象被引用次数超过 2^19 限制时,就轮到SideTable出场了。 首先,我们先看下超出限制之后,系统是如何将引用计数转移的 retian // 等价于直接使用对象调用retain方法 inline

weixin_43180925的博客 759

ArcGIS投影变换实战:从WGS_1984到Krasovsky_1940_Albers的精准转换

本文详细解析了在ArcGIS中如何将WGS_1984地理坐标系下的数据精准转换至Krasovsky_1940_Albers投影坐标系。文章通过实战案例,重点阐述了地理坐标系与投影坐标系的区别,并逐步演示了创建自定义地理变换、使用投影栅格工具以及进行批量处理和结果验证的核心操作流程,旨在解决地图数据叠加不准的常见问题。

weixin_29251131的博客 462

cocos2dx学习笔记之retain()和release()函数简介

retain的意思就是保持引用,避免被cocos2d-x释放。与之对应的就是release(). 和c++中的new(),delete()有点类似。 不过在coscos中由于autorelease的存在,问题变得更加复杂。 autorelease 对象调用autorelease,对象就会被cocos2d-x的内存管理机制标记,在游戏的每一帧,内存管理机制都要扫描被标记的对象,如果引用计数为零

shitangdejiaozi的博客 4623

手把手教你用Simulink搭建级联H桥储能变流器仿真模型(附SOC均衡分析)

本文详细介绍了如何使用Simulink搭建级联H桥储能变流器仿真模型,并附有SOC均衡分析。从仿真环境准备、单相H桥单元建模到多模块级联方案和SOC均衡策略实现,逐步指导读者完成复杂系统的构建与优化。通过关键仿真结果分析和工程实践问题排查,帮助读者掌握级联H桥储能变流器的核心技术与应用方法。

weixin_42524226的博客 445

android技术--------如何解决弹出键盘只影响当前fragment输入的窗口

题目比较长,也可能有很多人不明所以这东西有啥可写的,简单来说就是实现近似于Android Pad 上QQHD聊天的界面效果,搞了很长的事件,今天终于搞定。 android3.0新加了组件Fragment称之为碎片,对这个一无所知的请自觉补习。今天的阐述将基于此组件。 fragment可以放入activity中,并随activity的生命周期变化而变化,但当相应键盘事件的时候,就比较让人挠头了,

3505

C++ release retain代码

  class CC_DLL CCObject : public CCCopying { protected: // object id unsigned int m_uID; // count of refrence unsigned int m_uReference; // is the object autoreleased bool m_bMan...

459

从理论到实践:利用FilterSolutions高效设计7阶椭圆低通滤波器

本文详细介绍了如何利用FilterSolutions软件高效设计7阶椭圆低通滤波器。文章从理论入手,对比了巴特沃斯、切比雪夫等经典滤波器特性,阐述了在要求高衰减陡度(如62dB抑制)和严格通带波纹(0.2dB)时,椭圆滤波器是最优选择。通过分步实战教程,指导读者完成从软件参数设置、性能验证到实际电路布局与调试的全过程,助力射频与高速数字信号处理工程师将理论转化为可靠设计。

jupi8的博客 558

黑箱中的retain 和 release

在接口设计时,我们经常要考虑某些意义上的平衡。在内存管理中,Objective-C 同时为我们提供了增加引用计数的retain和减少引用计数的release方法。 这篇文章会在源代码层面介绍 Objective-C 中retain和release的实现,它们是如何达到平衡的。 从 retain 开始 如今我们已经进入了全面使用 ARC 的时代,几年前还经常使用的retain和release方法已经很难出现于我们的视野中了,绝大多数内存管理的实现细节都由编译器代劳。 在这里,我...

gcs的博客 563

基于STM32与HRTIM的四开关Buck-Boost双向DC-DC电源设计实战(附源码、仿真与设计解析)

本文详细介绍了基于STM32F334的HRTIM高分辨率定时器实现四开关Buck-Boost双向DC-DC电源的设计实战。通过精准的PWM控制、双环PID算法和智能模式切换逻辑,解决了电压震荡与效率优化等关键问题,并提供了完整的源码、PSIM仿真及参数计算,为高性能电源设计提供了实用参考。

7z8x2c4v6b9的博客 295

VASP+Multiwfn+VMD静电势计算与可视化全流程解析

静电势是表征分子与材料表面电荷分布的关键物理量,它通过求解泊松方程,将电子密度与原子核电荷在空间中的贡献结合起来,直观揭示体系的电子富集与缺失区域。这一性质在理解化学反应活性、分子间相互作用(如氢键、卤键)以及材料表面性质方面具有重要价值。在计算材料科学与量子化学领域,基于第一性原理计算获得高精度电子结构数据后,如何将其转化为可直观分析的静电势图,是连接理论计算与物理解释的关键技术环节。本文聚焦于构建一条高效、可控的端到端工作流,详细解析如何利用VASP进行高精度电子密度计算,通过专业波函数分析软件Mult

weixin_33733810的博客 427

引用计数与弱引用

简书:https://www.jianshu.com/p/ef6d9bf8fe59 gitHub:https://github.com/Draveness/Analyze/blob/master/contents/objc/黑箱中的%20retain%20和%20release.md

qq_17190231的博客 384

Pixhawk2.4.8接口及引脚定义

pixhawk2.4.8接口定义图解

加斯顿工程师的博客 8741

[黑马IOS自学第十五篇]对象内存管理

对象内存管理   栈区局部变量  (地址从高到低分配)局部变量的空间会自动回收 堆区 存放程序运行过程中动态分配-存储空间(从低到高分配) 管理范围:管理人和继承自nsobject对象,Oc 中new 类的实例对象 类会继承nsobject对象,对其他基本数据类型无效,先释放堆区的,在释放栈区   程序启动的时候 就加载到内存(全局变量尽可能少用) 由系统自动

wadeAD的博客 2750

在时间轴上联动多张内表:ABAP 的 PROVIDE ... ENDPROVIDE 区间联动迭代实战

PROVIDE 是 ABAP 中处理有效期区间数据的强大工具,它能自动将多张内表按时间维度切片并联合处理。其核心功能包括:指定区间边界字段(BOUNDS),定义外部总区间(BETWEEN),并通过工作区和标志位(VALID)标识每张表在当前子区间是否生效。该语法特别适合 HR 信息类型等有效期数据,能避免手动处理区间重叠、排序和空档等问题。使用时需注意字段投影(FIELDS)限制、工作区只读原则,以及异常处理(如区间重叠或未排序)。典型应用场景包括员工调岗记录、价格有效期管理等需要时间轴联动的业务逻辑。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1668

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

上一篇: 神秘的 isa 指针
下一篇: 神奇的 BlocksKit (一)
appdeveloperxg
博客等级 码龄11年 38粉丝 30原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值