VirtualView 简单总结起来就是用 XML 描述一个组件,用我们提供的工具编译成 .out 二进制文件,在集成了 VirtualView 的 App 里直接加载 .out 文件就可以得到一个组件,然后像使用普通 UIView 一样使用它就好了。
框架解决具体问题:
1.页面动态性
2.提升性能,虚拟组件,减少页面层级,layer组件
先从整体上预览一下整个方案的大体结构:
具体产品流程
.out文件数据段分组格式如下图:
格式 |
具体描述 |
备注 |
---|---|---|
ALIVV字符串 | 开头标识位 | |
major |
标记版本号 | |
minor |
标记版本号 | |
patch |
标记版本号 | |
mainLocation |
组件区起始位置 | 页面层级节点描述,树形结构 |
mainSize |
组件区长度 | |
stringLocation |
字符串区起始位置 | 自定义的字符串除重,[hashid,@"string"] |
stringSize |
字符串区长度 | |
exprLocation |
deprecated |
|
exprSize |
deprecated |
|
extraLocation |
deprecated |
|
extraSize |
deprecated |
本地X.out文件读取解析过程;根据文件组件的数据描述读取分段的数据,并且构造VVNodeCreater 的结构, VVNodeCreater和XML 的结构十分类似。具体流程如下图
解析完成,生成craters这个根节点的树后,装载属性、生成逻辑上的组件层级关系、创建组件相应的NA coacaview,组装成真正的NA View层级关系。
通过 rootnode 创建VVViewContainer的子view或是子layer
_rootNode.rootCanvasLayer = self.layer;
_rootNode.rootCocoaView = self;
基类 VVBaseNode 实现如下,又是一个递归调用
- (void)setRootCocoaView:(UIView *)rootCocoaView
{
_rootCocoaView = rootCocoaView;
for (VVBaseNode *subNode in self.subNodes) {
subNode.rootCocoaView = rootCocoaView;
}
}
- (void)setRootCanvasLayer:(CALayer *)rootCanvasLayer
{
_rootCanvasLayer = rootCanvasLayer;
for (VVBaseNode *subNode in self.subNodes) {
subNode.rootCanvasLayer = rootCanvasLayer;
}
}
NVVHLayout 容器组件 继承自VVBaseNode
- (void)setRootCocoaView:(UIView *)rootCocoaView
{
_rootCocoaView = rootCocoaView;
if (self.cocoaView.superview != rootCocoaView) {
if (self.cocoaView.superview) {
[self.cocoaView removeFromSuperview];
}
[rootCocoaView addSubview:self.cocoaView];
}
for (VVBaseNode *subNode in self.subNodes) {
subNode.rootCocoaView = self.cocoaView;
}
}
- (void)setRootCanvasLayer:(CALayer *)rootCanvasLayer
{
_rootCanvasLayer = rootCanvasLayer;
for (VVBaseNode *subNode in self.subNodes) {
subNode.rootCanvasLayer = self.cocoaView.layer;
}
}
控件组件 NVTextView 继承自VVBaseNode
- (void)setRootCocoaView:(UIView *)rootCocoaView
{
if (self.cocoaView.superview != rootCocoaView) {
if (self.cocoaView.superview) {
[self.cocoaView removeFromSuperview];
}
[rootCocoaView addSubview:self.cocoaView];
}
[super setRootCocoaView:rootCocoaView];
}
并且递归拿到所有的有表达式和action的node
+ (void)private_variableNodes:(VVBaseNode *)node result:(NSMutableArray *)result
{
if (node.expressionSetters.count > 0 || (node.action && node.action.length > 0)) {
[result addObject:node];
}
for (VVBaseNode *subNode in node.subNodes) {
[self private_variableNodes:subNode result:result];
}
}
至此,整个页面层级关系构建完成,接着,数据到来刷新界面展示及相关逻辑生效
完。。。。。