回调函数中删除调用者

在回调函数中有时需要删除调用该函数的类,比如网络回调函数中如果下载完成有时需要删掉该网络类,此时如果在该函数中删除了调用该函数的类,回调函数后面如果再使用该类的变量就会错误退出(kern-exec3),那么如何在回调函数中删除调用者呢?

 

CAsyncCallBack类可以解决解决这类问题。

 

实现的原理是这样的:由CAsyncCallBack来执行调用回调的操作,而在原来调用回调的地方执行CAsyncCallBack::CallBack()。

CAsyncCallBack是个Cactive,也就是说,调用者类在调用了CAsyncCallBack::CallBack(),会继续往下执行,完成后才会执行到CAsyncCallBack,这样删除调用者就没什么问题了。

 

CAsyncCallBack的用法:

 

因为在Gui的事件处理函数 比如像handleWsEventL或者offereyEvent或者handleCommand这些函数都是运行在CCoeEnv这个活动对象RunL里面的,为了不阻塞该Runl所以才要把一些需要等待的操作用AsyncCallBack的方式移出到别的RunL中执行

一般作为成员变量使用,以下是具体说明

1、定义:

 Class A

{

private: 

CAsyncCallBack* iCall;

}

2、初始化:

A::PreLayoutDynInitL()

{

     iCall = new (ELeave) CAsyncCallBack
TCallBack( LaunchDlgCallback, this ),
CActive::EPriorityStandard );

}

因为CAsyncCallBack是派生于CAtive的,这句话就是相当于Active的构造,只不过要传递一个TCallBack对象

TCallBack构造函数:inline TCallBack(TInt (*aFunction)(TAny* aPtr),TAny* aPtr);

TInt (*aFunction)(TAny* aPtr):函数地址,TAny* aPtr:对象地址

3、激活:

A::HandleCommandL()

{

if (!iCall->IsActive())

{

iCall->Call();//就 相当于Active的SetActive()了

}

因为这个AsyncCallBack是继承于CAsyncOneShot的,所以他的call里面实际有自激活的过程iThread.RequestComplete(pS,0); KErrNone = 0,即给当前线程信号量并且激活active。这样的话在ccoeenv的runl运行完,就可以进AsyncCallBack的runL了。

4、回调

RunL()

{

调用TCallBack的handler function.

}

5、回调函数定义

注意:1、回调用static的函数获得全局地址
      2、在使用  TAny* aDlg前要做 类型转换。

TInt A::LaunchDlgCallback( TAny* aDlg )
{
A* dlg = 
static_cast<CWVSettingsUIServerListDialog*>( aDlg );  
TRAP_IGNORE( dlg->DoLaunchCorrectDialogL() );

    return EFalse;
}

    在这里说一下为什么要用static的函数,因为callback使用系统,那么如果用类成员函数的话,会隐藏this指针在里面,调用还得 this->B()这样的话系统怎么知道this,所以要用static全局地址。这样不会通过this,而且用static还能保证干净的全局地 址空间,作用域就是当前编译单元。然后callback你没有this指针的话又不行,因为你 最终还要用成员函数,所以TCallBack要求你在用一个this指针作为参数传递过去,这样系统既知道你的函数地址还知道你的对象地址,其实他是把你转过来的对象地址扔到你的callback函数里,这样你回 调函数里一地址转换不久可以的到this了么。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值