输出 UIView 的层级结构
输出 UIViewController 的层级结构
输出类的属性与方法列表
形如[0xAbc …]调用时如何出现方法提示 [161129更新]
lldb 如何支持 frame 类型的输出 [161204更新]
UIView的层级结构
UIView+JAlldb.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14#import <UIKit/UIKit.h>
@interface UIView (JAlldb)
#if DEBUG
/**
* 输出view的层级结构
*/
- (void)p_recursiveView;
#endif
@end
UIView+JAlldb.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#import "UIView+JAlldb.h"
@implementation UIView (lldb)
#if DEBUG
- (void)p_recursiveView{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
// 私有方法
NSLog(@"%@",[self performSelector:@selector(recursiveDescription)]);
#pragma clang diagnostic pop
}
#endif
@end
UIViewController的层级结构
UIViewController+JAlldb.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14#import <UIKit/UIKit.h>
@interface UIViewController (JAlldb)
#if DEBUG
/**
* 输出指定vc的层级结构
*/
- (void)p_recursiveController;
#endif
@end
UIViewController+JAlldb.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#import "UIViewController+JAlldb.h"
@implementation UIViewController (JAlldb)
#if DEBUG
- (void)p_recursiveController{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
// 私有方法
NSLog(@"%@",[self performSelector:@selector(_printHierarchy)]);
#pragma clang diagnostic pop
}
#endif
@end
类的属性与方法列表
NSObject+JAlldb.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35#import <Foundation/Foundation.h>
@interface NSObject (JAlldb)
/**
属性列表
@param recursive 是否递归
@return 属性列表
*/
- (NSArray *)p_propertyList:(BOOL)recursive;
/**
变量列表
@param recursive 是否递归
@return 变量列表
*/
- (NSArray *)p_ivarList:(BOOL)recursive;
/**
* 方法列表
*
* @param recursive 是否递归
*/
- (NSArray *)p_methodList:(BOOL)recursive;
/**
清空缓存列表
*/
- (void)p_cleanCacheList;
@end
NSObject+JAlldb.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107#import "NSObject+JAlldb.h"
#import <objc/message.h>
@implementation NSObject (JAlldb)
const void* propertiesKey = "com.coder.lldb-exclusive.propertiesKey";
const void* ivarKey = "com.coder.lldb-exclusive.ivarKey";
const void* methodKey = "com.coder.lldb-exclusive.methodKey";
- (NSArray *)p_propertyList:(BOOL)recursive {
NSArray *glist = objc_getAssociatedObject([self class], propertiesKey);
return glist == nil ? ^{
unsigned int count = 0;
NSMutableArray *plistM = [NSMutableArray arrayWithCapacity:count];
Class cls = [self class];
do {
objc_property_t *list = class_copyPropertyList(cls, &count);
for (int i = 0; i < count; ++i) {
objc_property_t pty = list[i];
const char *pname = property_getName(pty);
[plistM addObject:[NSString stringWithUTF8String:pname]];
}
free(list);
cls = [cls superclass];
} while (cls && recursive);
objc_setAssociatedObject([self class],propertiesKey, plistM, OBJC_ASSOCIATION_COPY_NONATOMIC);
NSLog(@"Found %ld properties on %@",plistM.count,[self class]);
return plistM.copy;
}() : glist;
}
- (NSArray *)p_ivarList:(BOOL)recursive{
NSArray *glist = objc_getAssociatedObject([self class], ivarKey);
return glist == nil ? ^{
unsigned int count = 0;
NSMutableArray *plistM = [NSMutableArray arrayWithCapacity:count];
Class cls = [self class];
do {
Ivar *list = class_copyIvarList(cls, &count);
for (int i = 0; i < count; ++i) {
Ivar ity = list[i];
const char *iname = ivar_getName(ity);
[plistM addObject:[NSString stringWithUTF8String:iname]];
}
free(list);
cls = [cls superclass];
} while (cls && recursive);
NSLog(@"Found %ld ivar on %@",plistM.count,[self class]);
objc_setAssociatedObject([self class],ivarKey, plistM, OBJC_ASSOCIATION_COPY_NONATOMIC);
return plistM.copy;
}() : glist;
}
- (NSArray *)p_methodList:(BOOL)recursive {
NSArray *glist = objc_getAssociatedObject([self class], methodKey);
return glist == nil ? ^{
unsigned int methodCount = 0;
NSMutableArray *plistM = [NSMutableArray arrayWithCapacity:methodCount];
Class cls = [self class];
do {
Method *methods = class_copyMethodList(cls, &methodCount);
for (unsigned int i = 0; i < methodCount; i++) {
Method method = methods[i];
/*
printf("\t'%s'|'%s' of encoding '%s'\n",
class_getName(cls),
sel_getName(method_getName(method)),
method_getTypeEncoding(method));
*/
[plistM addObject:[NSString stringWithUTF8String:sel_getName(method_getName(method))]];
}
free(methods);
cls = [cls superclass];
}while (cls && recursive);
printf("Found %d methods on '%s'\n", methodCount, class_getName([self class]));
objc_setAssociatedObject([self class],ivarKey, plistM, OBJC_ASSOCIATION_COPY_NONATOMIC);
return plistM.copy;
}() : glist;
}
- (void)p_cleanCacheList {
objc_removeAssociatedObjects([self class]);
}
@end
[0xAbc …]调用如何出现方法提示
类地址前加类型强转
1
2(lldb) po [(UIView *)0x117e09e80 backgroundColor]
UIExtendedSRGBColorSpace 1 1 1 1
lldb如何支持frame类型的输出
1
2
3$ touch ~/.lldbinit
$ echo display @import UIKit >> ~/.lldbinit
$ echo target stop-hook add -o \”target stop-hook disable\” >> ~/.lldbinit