pod install
。#import <BKRecursiveDescription/BKRecursiveDescription.h>
添加到您的源文件(或前缀头文件,如果您想在整个项目中使用它)。- (void)bk_addRecursiveDescriptionToString:(NSMutableString *)string level:(NSUInteger)level
。[yourObject bk_recursiveDescription]
以获取包含对象递归描述的 NSString
。// Implemented in a class named "BKSomeClass" (adapted from the example project)
- (void)bk_addRecursiveDescriptionToString:(NSMutableString *)string level:(NSUInteger)level
{
DESCRIBE_SELF(string, self);
DESCRIBE_VARIABLE(string, level, _drawerPosition); // enum
DESCRIBE_VARIABLE(string, level, _bounds); // CGRect
DESCRIBE_VARIABLE(string, level, _drawerOffset); // CGFloat
DESCRIBE_VARIABLE(string, level, _drawerInsets); // UIEdgeInsets
DESCRIBE_VARIABLE(string, level, _acceptSpec); // NSObject with its own recursive description method
}
输出
<BKSomeClass: 0x15695620>
|_drawerPosition = (unsigned int)1
|_bounds = (CGRect){{0, 0}, {320, 568}}
|_drawerOffset = (float)198.500000
|_drawerInsets = (UIEdgeInsets){44, 0, 172.5, 0}
|_acceptSpec = <BKCameraRollButtonSpec: 0x15695790>
| |_bounds = (CGRect){{0, 0}, {40, 40}}
| |_center = (CGPoint){280, 168.5}
| |_alpha = (float)0.473901
Q: 那宏中的那个 string
和 level
是怎么回事?
A: 并非总便于在对象的树结构上递归实现一个递归描述方法,此时需要一定的灵活性以供实现。因此,直接提供正在构建的原始字符串。这也允许在组织属性描述时插入自定义字符串,例如标题或分隔符。
级别允许集合正确缩进其内容 - 或者,如果需要,可为复杂描述进行自定义实现以调整描述级别。大多数开发者不必担心这一点,只需简单传递未更改的参数即可。
Q: C11 泛型?
A: 嗯。如果不支持它们,则通过 #if __has_feature(c_generic_selections)
禁用。但是,如果您更喜欢,您仍然可以访问底层由泛型宏解析到的 C 函数,例如 _RD_DESCRIBE_CGRECT
。这些方法的声明指定它们始终应该是内联的。
顺便提一下,由于 C11 泛型似乎只选择 表达式,而不是 语句,因此需要这些 C 函数。
Q: 为什么会有 do {} while(0)
包裹?这甚至能做什么吗?
A: 嗯 - 这在 C 宏预处理器编程中是家常便饭。它将一系列语句组合成一个,这样花括号就不会在宏展开时破坏,例如,无括号 if 语句。
DESCRIBE_VARIABLE(string, level, variable)
variable
转换为字符串并用作描述中的名称,然后将宏解析到 DESCRIBE_VALUE
。DESCRIBE_VALUE(string, level, name, value)
string
中,根据参数类型进行格式化,使用 C11 泛型表达式。支持 float
、double
、short
、unsigned short
、int
、unsigned int
、long
、unsigned long
、long long
、unsigned long long
、BOOL
、CGPoint
、CGRect
、UIEdgeInsets
和 NSObject
(+ 子类)。DESCRIBE_SELF(string, object)
string
中。按照惯例,这是递归描述实现中的第一条语句。DESCRIBE_OBJECT(string, level, name, object)
name
的对象的描述追加到 string
中。如果 object
支持递归描述,将使用其递归描述。对象可能是 nil。DESCRIBE_VALUE_WITH_FORMAT(string, level, name, format, value)
string
中。