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()之前参数是有效的。