WAP之家:为您提供最全最新的WAP技术,CP.SP.3G等行业资讯。 WAP之家交流论坛全新开放 点击进入>>
WAP资讯 | 3G动态 | SP动态 | 运营商动态 | 内容商动态 | 制造商动态 | 论坛讨论>> 每次自动访问
WAP技术 | WAP源码 | 手机编程 | 手机源码 | 无线技术 | J2ME技术 | 手机软件 添加到收藏夹
IVR技术 | SP资料 | SMS MMS技术 | 商业方案 | IVR下载 | 书籍教程 | 工具软件 语言:繁體中文

WAP之家技术文章手机编程Symbian基础知识Symbian OS 精要

Symbian OS 精要
作者:未知  来源:转载  发布时间:2006-11-30 22:16:59

• 用可能不存在于您的析构函数中的变量调用函数。
例如,以下代码可能导致异常,因为有可能您在分配
内存之前您的对象已经被销毁,或者在应用程序的另
一处已经删除了该内存,这样iSomeServer 就会处
于NULL:
CMyClass::~CMyClass()
{
iSomeServer->Close();
delete iSomeServer;
}
应该如下编写代码:
CMyClass::~CMyClass()
{
if (iSomeServer)
{
iSomeServer->Close();
delete iSomeServer;
}
}
• 在NULL 指针上调用函数。
• 函数调用另一个函数,而其使用的变量已经超出范畴,
例如:把一个栈变量传送到一个异步函数的回调
(callback) 里。
6. 在系统资源不够的情况下,得体的处理失效情况是非
常重要的。最受限制的资源通常是系统RAM,因此
您需要注意正确的处理内存不足的情况。采用‘两段
构造方法’和如下所述的CleanupStack 机制,对这
种防御性编程来说是必不可少和极其重要的。
7. 对带“R”字头、具备Close()方法的类,总是使用
CleanupClosePushL()。这将确保当Leave 事件
发生时,它们会被恰当的清除。例如:
RFile file;
User::LeaveIfError(file.Open(…));
CleanupClosePushL(file);

CleanupStack::PopAndDestroy(&file);
对用Release()或Destroy()的‘R’ 类,亦可使用
CleanupDeletePushL()及
CleanupReleasePushL()来取代Close()。
8. 另外,请记住CleanupStack 机制是可扩展的,面
对所有Leave 事件,都可以用它来有效的清除任
何对象。即使您需要处理的是较复杂的情况,也
不应该忽略采用正规的清理机制。欲进一步了解
TCleanupItem,请参阅Symbian OS Library 文档。
9. 倘若您意图对HBufC 变量重新分配资源,在清除它
们之后,总是将其设为NULL。由于HBufC 的资源
分配或其再分配可能会导致Leave 事件的发生,从而
可能会出现析构函数试图删除已经不存在的HBufC
变量的情况。当然,对于任何由堆分配资源的变量而
言都应如此,对HBufC 变量采取此做法更是已经成
为普遍的使用模式。
10. 当必须采用自己的TRAP 时,请勿忽略所有的报错。
常见的编码错误是:
TRAPD(err, DoSomethingL());
if (err == KErrNone || err ==
KErrNotFound)
{
// Do something else
}
这意味着其他错误码都被忽略。然而,倘若您非用上
述模式不可,应采用Leave 机制来处理其他错误:
TRAPD(err, DoSomethingL());
if (err == KErrNone || err ==
KErrNotFound)
{
// Do something else
}
else
User::Leave(err);
11. 不要延误将对象PushL()到CleanupStack 上。所
有新创建的对象(成员变量除外)应被立即压入该堆
栈。例如,下面的作法是错的:
void doExampleL()
{
CSomeObject* myObject1=new (ELeave)
CSomeObject;
CSomeObject* myObject2=new (ELeave)
CSomeObject;

// Do something here with thevariables
CleanupStack::PushL(myObject1);
CleanupStack::PushL(myObject2);
// Do something more with the variables

CleanupStack::PopAndDestroy(2);
// myObject2, myObject1
}
因为myObject2 的创建可能失败,造成myObject1
“悬”在那里不能被清理。应该这样来实现:
void doExampleL()
{
CSomeObject* myObject1=new (ELeave)
CSomeObject;
CleanupStack::PushL(myObject1);
CSomeObject* myObject2=new (ELeave)
CSomeObject;
CleanupStack::PushL(myObject2);

// Do something here with the variables

CleanupStack::PopAndDestroy(2);
// myObject2, myObject1
}
12. 注意,那些名称有大写字母C 结尾的函数(例如
NewLC())会自动把其对象置于CleanupStack。
您不应该自己来将这些对象压入CleanupStack,
否则该对象会入栈两次。当您创建非成员变量并为其
分配内存时,这些由C 结尾的函数很有用。
13.“两段构造方法”是Symbian OS 内存管理的关键
部分。基本原则是Symbian OS 中的构造函数或析
构函数永远不应该发生Leave。倘若一个C++ 构造
函数Leave,构造过程未完成的对象得不到清理,
因为还没有生成指针指向该对象。为此,Symbian
OS 中的构造函数仅将该对象实例化,而后调用该
对象的ConstructL()函数,在其中将成员数据
实例化。一旦ConstructL()发生Leave,标准
的析构函数将被调用来清除所有至此已被成功分
配的成员变量。在您的编码中照用这一设计模式
来防止内存泄漏,至为关键。当您写每一行代码
时, 都应该问自己:“ 这一行代码能否发生
Leave ?”假如回答为“是”,则应考虑“是否所
有资源都将被释放?”。
14. 编码中请勿使用_L()宏——而应使用_LIT()。_L()
自Symbian OS v5 起已是‘不推荐使用’(deprecated),
它的问题在于它将调用TPtrC(const TText*)构造
函数,该构造函数会调用strlen()函数来计算该字串的长度。虽然这不会带来额外的RAM 开销,却会
在运行时占用更多CPU 周期。相反,宏_LIT()直接
创建了一个在编译时就全部实例化的对象,节省了构
造TPtrC 的CPU 开销。当然,您首先应该考虑的是
否应该使用硬编码的字符串常量,因为当您将来地方
化(localize)您的程序时,这种常量类型的描述符
(descriptor) 可能需要重新编码。
15. 当在函数参数中使用描述符(descriptor) 时,应缺省
使用基类。在大多数情况下,以const TDesC& 形
式来传递描述符。对可修改的描述符,则应使用
TDes&。
16. 当在函数中传递或返回对象时,应确保如果您拥有该
对象的所有权,您应负责将其清除! Symbian 采取
的约定是:函数中的指针表示所有权转移到调用者,
而使用引用则表示被传递对象的所有权仍属于原所
有者。
17. Active Objects 是Symbian OS 的重要特性之一。请仔细
研究SDK 文档、Symbian Developer Network 白皮书,
以充分理解其工作原理。下面是一些有用的窍门:
• 在RunL()内无需使用TRAP()。Active Scheduler
本身会TRAP 函数RunL()并在其发生Leave 时
调用CActive::RunError()。
• 为此,您应实现自己的RunError()函数来处
理从RunL()的Leave 事件。
• 保证RunL()操作尽可能简短。长时间运行的
RunL()将阻塞其他Active Objects。
• 总是实现DoCancel()函数,总是在AO 析构
函数中调用Cancel()。
18. 您应尽可能利用Active Object 框架机制。对于使用电
池供电的设备,在一个循环中紧密不断地进行轮流
检测(polling) 是极其不适当的,将带来

上一页  [1] [2] [3]  下一页

[] [返回上一页] [打 印]
文章评论

用户名: 查看更多评论

分 值:100分 85分 70分 55分 40分 25分 10分 0分

内 容:

         (注“”为必填内容。) 验证码: 验证码,看不清楚?请点击刷新验证码