特别地,今天不讲P话,我们直接开始。
selector是什么呢,是函数映射,Java之类的编程语言是自带的,但是C++是没有的,所以我们便可以用C++自带的函数指针来实现
typedef const void* SEL;
SEL NSSelectorFromString(const std::string& str) {
static std::mutex mutex;
static std::set<std::string> selectorStrings;
std::lock_guard<std::mutex> lock(mutex);
auto it = selectorStrings.find(str);
if (it != selectorStrings.end()) {
return reinterpret_cast<SEL>(&(*it));
} else {
auto result = selectorStrings.insert(str);
return reinterpret_cast<SEL>(&(*result.first));
}
}
给出一段代码。这一段代码首先定义了一种新的静态指针类型SEL,并且通过字符串的加入或查找返回SEL对象。加了个锁,可以保证使用时的线程及数据安全。
class Function {
public:
void print(std::vector<std::string> t) {
for (auto& i : t)
cout << i << " ";
cout << "\n";
}
void print() {
cout << " \n";
}
void perform(SEL selector, const std::vector<std::string>& args = {}) {
static const auto& handlerMap = getHandlerMap();
auto it = handlerMap.find(selector);
if (it != handlerMap.end()) {
it->second(this, args);
} else {
std::cerr << "Unrecognized selector" << std::endl;
}
}
private:
using Handler = std::function<void(Function*, const std::vector<std::string>&)>;
static const std::map<SEL, Handler>& getHandlerMap() {
static const std::map<SEL, Handler> handlerMap = {
{ NSSelectorFromString("print"),
[](Function* obj, const auto& args) { obj->print(); }},
{ NSSelectorFromString("printWithVector"),
[](Function* obj, const auto& args) { obj->print(args); }}
};
return handlerMap;
}
};
这一段代码则是实现了核心功能,定义了一个function类,首先定义了两个print函数,可以处理空或有参数的情况,如果空则输出空加换行,否则就输出要输出的参数。perform是function类最核心的内容,它处理了函数映射,在私有的getHandlerMap里面找寻要perform的SEL对象,当然getHandlerMap的实现是通过定义一个有Function类的指针与输出内容参数的Handler函数封装类型(我们一般在其他语言中称作闭包,你们可以理解为被储存起来的函数),然后定义一个静态的map,将Function类中的print和printWithVector字符串函数名转为SEL对象作为键,便于来储存调用对应函数的Handler对象。
selector(函数映射)实现对于编程语言对于函数调用处理时是很有意义的
好了,那我们如何来调用呢,比如以下代码
print("A")
我们可以拆成
{"print", "(", "\"A\"", ")"}
我们很容易发现,参数是"\"A\"",而我们调用一般去掉开头和结尾的"\"",由于有参数我们应调用printWithVector
以下是上述代码的调用代码
auto fun = Function();
auto actionStr = "printWithVector";
auto sel = NSSelectorFromString(actionStr);
fun.perform(sel, {"A"});