YourView源码研究与学习
YourView 研究
项目地址
https://github.com/TalkingData/YourView
由于项目比较老,运行起来时有个地方会报错,需要修改如下,在_snapWithSublayer的最前面增加判断width或height是否为0,为0的直接返回为空,否则会崩溃
1
2
3
4
5
6
7
8
9
# UIView+YVNodeInfo.m
-(NSString*)_snapWithSublayer:(BOOL)containSublayer
{
CGRect frameX = self.frame;
if (frameX.size.width <= 0 || frameX.size.height <= 0) {
return @"";
}
....
}
代码调用流程
1、启动Web服务器
1、利用项目启动时,所有类都会执行load方法, ,启动GCDWebServer服务器: TalkingDataSDKDemo/libyourview/main/Main.m-> +(void)load -> +(void)_main -> GCDWebServer
GET: -> Main._excuteCmd
2、请求App信息
GET url http://127.0.0.1:8080/?cmd=appinfo -> Main._excuteCmd -> 返回App相关信息
3、获取最新的view及相关信息
GET url: http://127.0.0.1:8080/?cmd=viewtree -> Main._excuteCmd -> 同步主流程 rootViewTreeDictionary -> 递归查下view及子节点view的信息 [keyWindow traversal:stepIn context:context] -> nodeInfo -> 每个view的信息 frame、相对于window的frame、_snapWithSublayer
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
// "YVTraversalStepin.h"
// 层级信息
(lldb) po [stepined stepinfo]
{
"assign_to_viewcontroller" = "";
"index_row" = "-1";
"index_section" = "-1";
"is_in_collectionview" = 0;
"is_in_tableview" = 0;
"view_deepth" = 0;
"view_level" = "/0";
}
// "NSObject+YVNodeInfo.h"
// 类,地址、继承关系
po superinfo
{
address = 0x10361cfc0; // [NSString stringWithFormat:@"%p",self]
class = UIWindow; // NSStringFromClass(self.class)
inherit = "UIWindow:UIView:UIResponder:NSObject"; // 不断递归找到superClass
}
// "UIView+YVNodeInfo.h"
// layer的截图的base64、frame
po selfinfo
{
isoffscreen = 0;
localframe = "{0, 0, 393, 852}";
snapshot = "iVBORw0KGgoAA...";
windowframe = "{0, 0, 393, 852}";
}
// "UIView+YVTraversal.h"
// 记录每个view及subview的address,以及记录总view数量
po extraInfo
{
screeninfo = "{0, 0, 393, 852}";
totalcount = 55;
}
// respons 返回的内容:
{
"viewtree": stepinfo + nodeInfo=(superInfo+selfInfo),
"extraInfo": extraInfo
}
+
4、点击Here,摇动选择的view
GET url: http://127.0.0.1:8080/?cmd=shake&address=0x1036181b0 -> Main._excuteCmd -> 根据address找到缓存的view[[YVObjectManager sharedInstance].context.viewMap objectForKey:addresss] -> shake2 -> 执行layer的transform.translation.x 动画
5、跟新选中view的frame
POST url: http://127.0.0.1:8080/?cmd=setframe&address=0x10368b9f0-> 根据address找到缓存的view[[YVObjectManager sharedInstance].context.viewMap objectForKey:addresss] -> setFrame -> 执行
Mac端软件展示逻辑
1、填写ip并点击按钮
buttonPressed -> "http://%@:8080?cmd=appinfo" -> onAppInfoSuccess -> requestViewTree -> http://"http://%@:8080?cmd=viewtree" -> [windowController updateViewTree:dict] -> notifyDataSuccess -> 通知YVViewTreeDidLoadNotificationName
2、点击刷新按钮
onRefreshButtonEvent -> "http://%@:8080?cmd=viewtree" -> notifyDataSuccess -> 通知YVViewTreeDidLoadNotificationName
左侧树形结构 YVLeftViewController -> YVViewTreeDidLoadNotificationName -> dataOK -> viewTree -> dataSource -> reloadData -> NSOutlineView
中间UI展示 YVMiddleViewController -> YVViewTreeDidLoadNotificationName -> dataOK -> viewTree -> dataSource -> createView -> NSNode + snapshot



