Symbian内存管理及编码规范

Symbian的内存管理

  对于手机来讲,内存资源是非常有限的,良好的内存分配管理机制是非常重要.如要内存没有很好的分配及捕获清理, 会导致内存溢出、数据丢失,系统崩溃,或者有一些意想不到的灾难性后果发生.

在讨论内存管理之前,要明白两个关于内存的二个很重要的概念:堆、栈,传统的数据类型变量及类成员变量的内存是分步在栈上的,堆内存是通过关键字new或(New(Eleave))来实例化的,在Symbian中,堆类是从CBase类继承的,是通过指针来引用的.

在处理一个函数状态时,只有二种状态,一是成功,二是失败;Symbian在成功时,返回KErrNone(KErrNone的值是0),失败返回一个错误码如(KErrNotFound,KErrNoMemory,)。良好的编程习惯是在调用后,无论是否有错,用if语句进行判断;

Symbian在内存管理机制上做得非常的好,采用了不同平台的独特机制:
1.陷井
   Symbian提供了二个宏用来陷井捕获:
   设置陷井: 
   TRAP宏  TRAP(error,function())
   TRAPD宏 TRAPD(error,Function())
   以上二个宏基本上相似,区别在于:TRAP宏在使用之前,要先定义里面的变量error,而TRAPD中的error变量无需定义,包含了TInt error该段代码.要注意的是error参数是TInt类型.
   捕获陷井:
       Symbian通过一个User静态类来进行返回错误码,例如:
      User::Leave(code)
      User::LeaveNoMemory()
      User::LeaveIfError(error)
      User::LeaveIfNull(TAny* ptr)
   如果没有捕获到错误,error的值就是0.反之则是非0值;
  例:
  void Fun1()
 {
    TInt err = 0;
    TRAP(err,Fun2L());
    if(!(0==err))
    {  
         错误处理
   }
   else
    {
            
    }

 }

 void Fun2L()--------------------------------------注意函数名:Fun2L()
{
   TInt iValue = 0;
   if   (0==iValue)
       User::Leave(1);
}  
采取陷井捕获异常,程序的效率不高,关于陷井的运行效率,在这里就不多说明了。呵呵
2. 压栈清理
 压栈清理是Symbian的独特机制,在对内存处理非常独特,指针变量可以压到清理栈,如果发生异常,由清理栈负责回收内存,如果没发生异常,应手动将其弹出栈,Symbian提供了一个静态类CleanupStack的API负责处理;
void FunL()
{
   CPerson* person = new(ELeave)CPerson;
   /*注意:Symbian重载了new操作符,new(ELeave)用于在分配内存时出现异常,清理栈会自动清除该块内存,避免野指针的情况发生.
   */
   CleanupStack::PushL(person);//将person压入栈
   ....
   CleanupStack::Pop(person);//从清理栈弹出压入的person;
  //或者使用另:CleanupStack::PopDestory(1);或者CleanupStack::PopDestory(person);//

}
3.二重构造
Symbian提出的二重构造概念,同样在C++和java中可以使用.但JAVA是由虚拟机自动回收内存.二重构造是通过类的一个静态方法NewL/NewLC,进行构造对象,能过在NewL/NewLC构造的方法调用ConstructL()方法进行初始化成员函数.从而避免了分配内存成功但进行构造对象时出现错误的现象.在NewL/NewLC中进行压栈,如果分配内存失败,则由清理栈处理内存的回收.如果分配内存成功,便调用ConstrucL进行初始化成员变量.
注意:如果用户自定义的类是C类,是必须要继承CBase.
class CPerson : public CBase
{
   private:
      CPerson();
      void ConstructL(TInt age,char* apname); 

   public:
      static CPerson* NewL(TInt age,char* apname);      
};

CPerson::Cperson* NewL(TInt age,char* apname)
{
   char* ipName = new char[strlen(apname)+2]; 
   strcpy(ipName,apname);
   CPerson person = new(ELeave)CPerson;    
   CleanupStack::PushL(person);
   person->ConstructL(age,apname);
   CleanupStack::Pop(person);//或者CleanupStack::PopDestroy(1)或者CleanupStack::PopDestroy(person);
}
...

发生任何不可恢复的错误时,会出现严重的错误panic,具体panic下次在讨论.

二、Symbian命名约定

我老师经常对我讲过一句话“代码是写给人看的.”,这句话是很有道理的,也就是说遵守一定的命名约定,有助于同行交流。
关于类,Symbian大致分了四种类:T(数据类型类)、C(派生于CBase的堆分配类,)、R(资源类)、M(接口类).当然,定义不同的类时,应在类名前加类的前缀(T、C、R、M)。
1.类的成员变量应以i开头,函数参数应以"a"开头;
class TMyClass
{
   TInt iMyValue;
   void MyAddFunc(TInt aArg1,TInt aArg2);  
   void MyAddFuncL(TInt aArg1,TInt aArg2);-------->后缀L的约定是该函数可能产生异常退出;  
   void MyAddFuncLC(TInt aArg1,TInt aArg2); ---------->后缀LC的约定表示成功完成之后,返回值会被压入清理栈中;
};

2.常量应加前缀K.      const CInt KMyconstant;

3.枚举应加T开头
enum TColors
{
   ERed,
   EGreen
}

4.宏全部为大写
#define MY_HARDCODED_VALUE (25)

5.

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值