Runtime源码中的DisguisedPtr
2022-02-11 本文已影响0人
helinyu
头文件: objc-private.h
DisguisedPtr : 指针伪装、指针封装、掩饰指针
DisguisedPtr<T>通过运算使指针隐藏于系统工具(如 leaks 工具),同时保持指针的能力,其作用是通过计算把保存的 T 的指针隐藏起来,实现指针到整数的映射。
template <typename T>
class DisguisedPtr {
// typedef unsigned long uintptr_t;
// 无符号 long 类型的 value 成员变量
uintptr_t value;
static uintptr_t disguise(T* ptr) { // 指针隐藏
// 相当于直接把 T 指针的地址转化为 unsigned long 并取负值
return -(uintptr_t)ptr;
}
static T* undisguise(uintptr_t val) { // 指针显示
// 把 val 转为指针地址,对应上面的 disguise 函数
return (T*)-val;
}
public:
DisguisedPtr() { } // 构造函数
// 初始化列表,显式初始化 value 成员变量
DisguisedPtr(T* ptr) : value(disguise(ptr)) { } // 指针隐藏
DisguisedPtr(const DisguisedPtr<T>& ptr) : value(ptr.value) { }
// T* 赋值函数
DisguisedPtr<T>& operator = (T* rhs) {
value = disguise(rhs);
return *this;
}
// 引用赋值函数
DisguisedPtr<T>& operator = (const DisguisedPtr<T>& rhs) {
value = rhs.value;
return *this;
}
// 重载运算符
operator T* () const {
// 转为指针
return undisguise(value);
}
T* operator -> () const {
// 转为指针
return undisguise(value);
}
T& operator * () const {
// 转化为指针并取出该指针指向的内容
return *undisguise(value);
}
T& operator [] (size_t i) const {
return undisguise(value)[i];
}
};
// fixme type id is weird and not identical to objc_object*
static inline bool operator == (DisguisedPtr<objc_object> lhs, id rhs) {
return lhs == (objc_object *)rhs;
}
static inline bool operator != (DisguisedPtr<objc_object> lhs, id rhs) {
return lhs != (objc_object *)rhs;
}
PS: 为什么要处理处理这个将值转化为负数?
地址 —— long —— 地址 : 起到了保护的作用。
只需要知道DisguisedPtr<T>功能上等价于T*即可