原理图:
    dyna 整体流程.png

    使用的技术点:

    • 服务端:
      • express 创建服务器应用
      • ws插件提供websocket服务
      • chokidar插件提供监听文件夹改动服务
      • fs插件提供文件读写功能
      • path插件提供路径操作
      • pm2插件 提供dyna服务脱离终端长久运行的功能
    • 客户端:

      • SocketRocket三方库提供websocket连接功能

      • 对于.out文件仿照官方,使用base64传递给客户端

      • 客户端的UI刷新:

    因为是开发阶段的工具,建议刷新规则以整体为准,因为VirtualView的局部刷新方法并不靠谱,可以去看VVViewContainer的updateData方法,它只会刷新带有表达式的属性,普通属性并不会刷新

    1. /// VVViewContainer的刷新源码
    2. - (void)updateData:(id)data
    3. {
    4. if (data != self.lastData) {
    5. self.lastData = data;
    6. for (VVBaseNode *node in _variableNodes) {
    7. [node reset];
    8. for (VVPropertyExpressionSetter *setter in node.expressionSetters.allValues) {
    9. if ([setter isKindOfClass:[VVPropertyExpressionSetter class]]) {
    10. [setter applyToNode:node withObject:data];
    11. }
    12. }
    13. if ([data isKindOfClass:[NSDictionary class]]) {
    14. NSDictionary *dict = (NSDictionary *)data;
    15. node.actionValue = [dict objectForKey:node.action];
    16. }
    17. [node didUpdated];
    18. }
    19. }
    20. }

    作者通过给VVViewContainer加分类,调用以下代码实现了vv模板视图的全属性刷新,这只作为debug模式下热重载使用,不建议release下使用

    1. /// 作者实现的模板全属性刷新
    2. #import "VVViewContainer+ZPNDRefreshSupport.h"
    3. @implementation VVViewContainer (ZPNDRefreshSupport)
    4. + (void)load{
    5. static dispatch_once_t onceToken;
    6. dispatch_once(&onceToken, ^{
    7. Method originalMethod = class_getInstanceMethod(self, @selector(updateData:));
    8. Method myMethod = class_getInstanceMethod(self,@selector(hook_updateData:));
    9. method_exchangeImplementations(originalMethod, myMethod);
    10. });
    11. }
    12. - (void)hook_updateData:(id)data
    13. {
    14. if (data != [self valueForKey:@"lastData"]) {
    15. VVNodeCreater *creater = [[[VVTemplateManager sharedManager] valueForKey:@"creaters"] valueForKey:self.rootNode.templateType];
    16. [self _refreshPropertyOfNode:self.rootNode creater:creater data:data];
    17. }
    18. [self hook_updateData:data];
    19. }
    20. - (void)_refreshPropertyOfNode:(VVBaseNode *)node creater:(VVNodeCreater *)creater data:(id)data
    21. {
    22. for (VVPropertySetter *setter in creater.propertySetters) {
    23. if (![setter isKindOfClass:[VVPropertyExpressionSetter class]]) {
    24. [setter applyToNode:node withObject:data];
    25. }
    26. }
    27. if (node.subNodes) {
    28. for (NSInteger i = 0; i < node.subNodes.count; ++i) {
    29. VVBaseNode *subNode = node.subNodes[i];
    30. VVNodeCreater *subCreater = creater.subCreaters[i];
    31. [self _refreshPropertyOfNode:subNode creater:subCreater data:data];
    32. }
    33. }
    34. }
    35. @end

    如果是一个列表中某个cell或item的模板有改动,建议刷新整个列表,以保证整体高度分配正确