Chromium Base学习笔记 —— Callback

Callback对象在传递过程中,必须是const-reference类型。


基本用法如下:

int Return5() { return 5; }
base::Callback<int(void)> func_cb = 
base::Bind(&Return5);
LOG(INFO) << func_cb.Run();  // Prints 5.

绑定类方法:

绑定类方法的时候,该Class必须继承自RefCounted。如果需要在Thread中传递,那么需要保证线程安全(RefCountedThreadSafe)

   class Ref : public base::RefCountedThreadSafe<Ref> {
    public:
     int Foo() { return 3; }
     void PrintBye() { LOG(INFO) << "bye."; }
   };
   scoped_refptr<Ref> ref = new Ref();
   base::Callback<void(void)> ref_cb = base::Bind(&Ref::Foo, ref);
   LOG(INFO) << ref_cb.Run();  // Prints out 3.

// MISSING FUNCTIONALITY
//  - Binding arrays to functions that take a non-const pointer.
//    Example:
//      void Foo(const char* ptr);
//      void Bar(char* ptr);
//      Bind(&Foo, "test");
//      Bind(&Bar, "test");  // This fails because ptr is not const.

使用Run方法运行:

void DoSomething(const base::Callback<void(int, std::string)>& callback) {
    callback.Run(5, "hello");
}

// 可以重复使用Callback:
void DoSomething(const base::Callback<double(double)>& callback) {
  double myresult = callback.Run(3.14159);
  myresult += callback.Run(2.71828);
}

1. PASSING UNBOUND INPUT PARAMETERS

void MyFunc(int i, const std::string& str) {}
base::Callback<void(int, const std::string&)> cb = base::Bind(&MyFunc);
cb.Run(23, "hello, world");

2. PASSING BOUND INPUT PARAMETERS

void MyFunc(int i, const std::string& str) {}
base::Callback<void(void)> cb = base::Bind(&MyFunc, 23, "hello world");
cb.Run();

//A callback with no unbound input parameters (base::Callback<void(void)>)
//is called a base::Closure. So we could have also written:

base::Closure cb = base::Bind(&MyFunc, 23, "hello world");

//   When calling member functions, bound parameters just go after the object
//   pointer.
//
base::Closure cb = base::Bind(&MyClass::MyFunc, this, 23, "hello world");

3. PARTIAL BINDING OF PARAMETERS

   void MyFunc(int i, const std::string& str) {}
   base::Callback<void(const std::string&)> cb = base::Bind(&MyFunc, 23);
   cb.Run("hello world");

高级用法:

1. 通过WeakPtr绑定类方法:不是线程安全的,只能在单线程中使用

base::Bind(&MyClass::Foo, GetWeakPtr());

2. 手动管理This的声明周期,也就是this的拥有权不归Callback所有

base::Bind(&MyClass::Foo, base::Unretained(this));

3. 与2相反,This指针归Callback所有,Callback被destroy的时候,this也会被delete掉。

//   MyClass* myclass = new MyClass;
//   base::Bind(&MyClass::Foo, base::Owned(myclass));

4. 忽略返回值的情况

int DoSomething(int arg) { cout << arg << endl; }
base::Callback<void<int>) cb =
     base::Bind(base::IgnoreResult(&DoSomething));


Quick reference for binding parameters to Bind():

关于Closure:A callback with no parameters or no unbound parameters is called a Closure (base::Callback<void(void)> and base::Closure are the same thing).

(1)With No Parameters:

base::Callback<void(void)>

(2)No Unbound Parameters:

void MyFunc(int i, const std::string& str) {}
base::Callback<void(void)> cb = base::Bind(&MyFunc, 23, "hello world");
cb.Run();

PASSING PARAMETERS OWNED BY THE CALLBACK:

void Foo(int* arg) { cout << *arg << endl; }
int* pn = new int(1);
base::Closure foo_callback = base::Bind(&foo, base::Owned(pn));
//   The parameter will be deleted when the callback is destroyed, even if it's
//   not run (like if you post a task during shutdown).

PASSING PARAMETERS AS A scoped_ptr:

void TakesOwnership(scoped_ptr<Foo> arg) {}
scoped_ptr<Foo> f(new Foo);
// f becomes null during the following call.
base::Closure cb = base::Bind(&TakesOwnership, base::Passed(&f));
//   Ownership of the parameter will be with the callback until the it is run,
//   when ownership is passed to the callback function. This means the callback
//   can only be run once. If the callback is never run, it will delete the
//   object when it's destroyed.
//     arg的生命周期是TakesOwnership的函数执行结束

PASSING PARAMETERS AS A scoped_refptr:

void TakesOneRef(scoped_refptr<Foo> arg) {}
scoped_refptr<Foo> f(new Foo)
base::Closure cb = base::Bind(&TakesOneRef, f);
//   This should "just work." The closure will take a reference as long as it
//   is alive, and another reference will be taken for the called function.

PASSING PARAMETERS BY REFERENCE:

//   Const references are *copied* unless ConstRef is used. Example:
//
void foo(const int& arg) { printf("%d %p\n", arg, &arg); }
int n = 1;
base::Closure has_copy = base::Bind(&foo, n);
base::Closure has_ref = base::Bind(&foo, base::ConstRef(n));
n = 2;
foo(n);                        // Prints "2 0xaaaaaaaaaaaa"
has_copy.Run();                // Prints "1 0xbbbbbbbbbbbb"
has_ref.Run();                 // Prints "2 0xaaaaaaaaaaaa"
//   Normally parameters are copied in the closure. DANGER: ConstRef stores a
//   const reference instead, referencing the original parameter. This means
//   that you must ensure the object outlives the callback!
//   ConstRef存储的是参数的引用,而不是参数的拷贝。所以使用ConstRef要确保Run()之前参数是有效的。





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值