Symbian CleanupStack工作机制解析[1]

  对于Symbian OS中使用的CleanupStack机制,在这里不作好坏的评价,既然选择了在Symbian平台上开发,那最重要的就是了解它的机制,掌握并高效的利用好它。

       对于在Symbian平台上开发GUI或者Server程序,CleanupStack已由框架创建,用户可直接使用CleanupStack::PushL()CleanupStack::Pop()等方法来控制可能的异常。在这样的框架下,用户无法了解CleanupStack是如何被创建,是如何工作的。

       当在Symbian平台上开发Console程序或者使用多线程时,异常清理栈CleanupStack就必须由用户自己创建和维护。Symbian封装了其中的核心机制,使得用户可以非常方便的创建CleanupStack清理栈并使用它。典型的代码如下:

  1.  
  2. TInt ThreadEntry(TAny *arg)     //用户线程的入口函数
  3. {
  4.     TInt retCode = 0;                        //函数异常退出的错误代码
  5.     CTrapCleanup* cleanupstack = CTrapCleanup::New();  //创建CleanupStack清理栈
  6.     if(cleanupstack == NULL)    
  7.            return -1;
  8.        TRAP(retCode,Fun_EntryL());   //捕获Fun_EntryL()异常退出
  9.        If(retCode != KerrNone)
  10.        {
  11.               //Handle_Error();
  12.        }
  13. delete cleanupstack;
  14.     return retCode;
  15. }
  16.  
  17. Void Fun_EntryL()
  18. {
  19.     CTestObj *obj = CTestObj::NewL();  //创建CTestObj时可能Leave
  20.     CleanupStack::PushL(obj);
  21.     Obj->FuncMayLeaveL();              // FuncMayLeaveL()方法调用可能Leave
  22.     CleanupStack::PopAndDestroy();
  23. }
  24.  

       上述主要的方法已做大致的说明,接下去具体分析CleanupStack清理栈创建和工作过程。CleanupStack类只是Symbian OS提供的针对清理栈的静态类,也就是工具类,Symbian OS中真正的清理栈功能是由CCleanup实现的。但如上述代码,我们在创建清理栈时并没有直接创建CCleanup对象,而使用CTrapCleanup::New()方法创建了一个CTrapCleanup对象,这其中就是核心所在。

       当调用CTrapCleanup::New()方法时,真正做了什么?首先,要使用清理栈,则必须创建CCleanup对象;其次在CTrapCleanup中创建了一个TCleanupTrapHandler对象。在创建了这些对象后,调用User::SetTrapHandler()将生成的TCleanupTrapHandler安装到当前线程中以备后用。

       在用户线程中,当调用可能Leave的方法时,必须用TRAP/TRAPD宏加以捕获。TRAP/TRAPD宏调用TCleanupTrapHandler::Trap()以标志开始异常捕获,当被TRAP宏监视的函数Leave时,调用TCleanupTrapHandler::Leave()方法控制其CCleanup对象完成之前已压入清理栈的对象;当被TRAP监视的函数正常时,调用TCleanupTrapHandler::UnTrap()方法取消异常捕获。

       同样,在可能Leave的方法中,如上述的Fun_EntryL(),当调用CleanupStack::PushL(obj)方法时,其内部是通过User::TrapHandler()获得当前线程中已安装的TCleanupTrapHandler对象,然后通过TCleanupTrapHandler::Cleanup()获得清理栈类,最后由清理栈类真正完成压栈、出栈和异常时栈内对象的内存释放。

       总结,清理栈的工作是以一个TRAP/TRAPD为单位的,在被某个TRAP宏监视的代码段内压入清理栈的对象,当出现异常Leave时,这些对象都能通过清理栈完成内存释放,不会导致内存泄露。但在不同TRAP宏压入的对象,在上述情况下是无法释放的,这点需要注意

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值