Symbian CleanupStack工作机制解析[1]

本文详细介绍了SymbianOS平台上的CleanupStack机制。包括如何创建和维护CleanupStack,以及如何利用它来处理异常情况,防止内存泄漏等问题。特别强调了在不同TRAP宏之间压栈对象的区别。
 对于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宏压入的对象,在上述情况下是无法释放的,这点需要注意

已经博主授权,源码转载自 https://pan.quark.cn/s/a4b39357ea24 常见问题解答 网页打开速度慢或者打不开网页? 受到多种因素的影响,对于非会员用户我们无法提供最优质的服务。 如果您希望得到最棒的体验,请至大会员页面("右上角菜单 → 大会员")根据说明操作。 请注意:受制于国际网络的诸多不确定性,我们无法对任何服务的可靠性做出任何保证。 如果出现了网络连接相关的问题,我们建议您先等待一段时间,之后再重试。 如果您在重试后发现问题仍然存在,请联系我们,并说明网络问题持续的时间。 图片下载后无法找到? 打开"右上角菜单 → 更多 → 修改下载路径",在弹出的对话框中可以看到当前图片的保存路径。 此外,由于网络因素,在保存图片之后,等待屏幕下方出现"已保存到..."后,才能在本地找到图片。 如何更改图片保存的目录? 请参见"右上角菜单 → 更多 → 修改下载路径"。 翻页不方便? 在点进某个图片后,通过在图片上向左或向右滑动,即可翻页查看下一个作品。 如何保存原图/导出动图? 长按图片/动图,在弹出的菜单中选择保存/导出即可。 输入账号密码后出现"进行人机身份验证"? 此为pixiv登陆时的验证码,请按照要求点击方框或图片。 在pxvr中注册pixiv账号后,收到验证邮件,无法访问邮件中的验证链接? 请复制邮件中的链接,打开pxvr中的"右上角菜单 → 输入地址"进行访问。 能否自动将页面内容翻译为汉语? 很抱歉,pxvr暂不提供语言翻译服务。 图片下载类型是否可以选择? 能否批量下载/批量管理下载? 已支持批量下载多图作品中的所有原图:找到一个多图作品,进入详情页面后,点击图片进入多图浏览模式,长按任意一张图片即可看到批量下载选项。 关于上述其他功能,我们...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值