[深入分析BREW机制]:BREW接口的引用计数机制

 BREW接口的引用计数机制
 ——目录——
 引言
 1、new函数规则一
 2、new函数规则二
 3、AddRef函数规则
 4、Release函数规则
 5、接口指针作为函数入参规则一
 6、接口指针作为函数入参规则二
 7、接口指针获取规则
 结语

引言
所有BREW接口的实现结构体里都有一个成员uint32 m_nRef,这就是常说的引用计数值,而引用计数机制就是通过管理m_nRef来管理接口的生命期,接口的生命期就是接口在内存中所呆的时间。
BREW的引用计数机制是符合com规范的,或者说按照com规范来理解和使用BREW的引用计数机制是安全的。
针对BREW的具体应用环境,我总结出如下几条使用规则:
1、new函数规则一
在new函数里将接口本身的数据成员m_nRef初始化为1。
(我把接口现实里的创建接口的函数称为new函数,因为它的函数名中习惯上都会带有new字样,new函数在AEEClsCreateInstance函数里被调用,赋有分配接口实例的内存和初始化接口实例的数据的功能。)
2、new函数规则二
除了m_nRef是接口的必备数据成员外,m_pIShell和m_pIModule也应成为必备。m_pIShell、m_pIModule由new函数接收AEEClsCreateInstance函数的对应入参(IShell *)、(IModule *)来赋值。除了赋值之外,new函数还应调用IShell和IModule接口的AddRef函数:
IShell_AddRef(pme->m_pIShell);
IModule_AddRef(pme->m_pIModule);
3、AddRef函数规则
AddRef的作用就是将接口自身的m_nRef加1,然后将m_nRef作为返回值。
4、Release函数规则
Release函数的作用与AddRef相反,将m_nRef减1,如果减完之后,m_nRef的值等于0,则要释放接口实例所占内存,千万忘的一点是如果实例结构体里有指针成员,则要先释放这些指针成员所指向的内存,比如,在new函数里调用了m_pIShell和m_pIModule的AddRef函数,在这里就要调用它们的Release函数。像m_pIShell属于全局性的成员,生命期与接口实例同,在接口的整个生命期中,供给接口的各个接口函数使用。
5、接口指针作为函数入参规则一
如果能确定函数A都是在其它函数的内部被调用,这种情况下,A的生命期一般都嵌套在调用者的生命期里。如果A使用了接口指针入参,那么在函数A的开头和结尾都不需要调用此接口指针的AddRef和Release函数,也就是说直接使用就行了,不必担心接口指针的分配与释放问题。
6、接口指针作为函数入参规则二
如果函数A属于回调函数供回调使用,这种情况下,A的生命期与调用者的生命期是异步的,如果函数A的参数中有接口指针入参,为了保证A在使用这个调用者传入的接口指针时,此接口指针还是有效的,就需要调用者只创建和传入此接口指针而不用释放。这样函数A的工作就是在使用接口指针前不要调用AddRef,但在使用完之后一定要调用此接口指针的Release函数。
7、接口指针获取规则
获取一个接口指针IImageCtl *pa的方法有三种:1)直接创建,IShell_CreateInstance(....&pa); 2)通过函数B的返回值或输出参数得到,3)直接将另一个IImageCtl *pb赋给它,即pa = pb形式。对于第1)、2)种获取方法,不需调用pa的AddRef函数,但要在使用完后调用Release函数;对于第3)种获取方法,原则上要调用pa的AddRef,并且在使用完后要调用pa的Release,但实际上往往可以省去这一对调用。具体为:如果pa的生命期嵌套在pb的生命期里,则可省,典型的例子是:pa是函数的入参,调用者将pb传给此入参,而pb的释放在被调函数返回之后进行,实际就是规则5。如果pa是一个全局性的变量,比如一个applet结构体的成员、一个接口结构体的成员,赋值一次要供applet或接口的所有函数使用,这时pa被赋值之后要调用AddRef,而Release要在applet的free函数或接口的release函数里调用。如果pa的生命期与pb是异步的,则也要调用,实际上规则6说的就是这种情况。

结语
引用计数看似很深奥,其实大多数情况下不必太关注,除了上面的规则之外,要记住下面几个原则会让你省去很多麻烦:1)看见CreateInstance,别忘Release;2)少用AddRef,用了AddRef,也别忘Release;3)AddRef和Release的返回值不要用;
最后具个例子帮你应用上面的规则:BREW的有些接口指针的获取不是直接调用CreateInstance,而是通过别的接口函数来得到,如IDatabase指针、IIFile指针、IImage指针等等,获取这些接口指针后,不必调用它们的AddRef函数,但是在使用完之后仍要调用它们的Release函数,这属于规则7里所说的第三者2)种获取接口指针的方法。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值