美文网首页iOS 杂货铺
objc 中最好的多行字符串声明方式

objc 中最好的多行字符串声明方式

作者: hite和落雁 | 来源:发表于2019-04-19 15:11 被阅读4次

    1. 问题

    在 AppHost.framework【注1】(以下简称 AppHost) 的编码中,需要处理很多预先导入到 webview 里的 js 文件,有一些不关键功能是用 .js 的文件读到内存的,还有一些比较短小的 js 源码,如;

              (function(e){
                    e.setAttribute('src','%@');
                    document.getElementsByTagName('body')[0].appendChild(e);
                })(document.createElement('script'));
    

    要写到代码里和 objc 代码一起。还有,在 AppHost 里,有个 ah_doc 模块,在编写注释时,需要输出完整的 js 代码,如

    window.appHost.invoke('startNewPage', { 'url': 'http://you.163.com/','title': 'title',
        'type': "push",
        'backPageParameter': {
            'url': 'http://qian.163.com',
            'title': 'title',
            'type': 'push'
        }
    })
    

    这个字符串里包含了大量的单引号、双引号,而且为了保持可读性、维护性,需要多行输出。

    这是非常典型的问题,传统的多行字符串声明有没有方法很好的解决?

    2.常见多行声明方式

    1. 利用@""包裹起来,换行
    NSString *a = @"[AppHost] "
        @"It is called \"jsbridge\"."
        @"like window.ah('ready') = function(){};"
        @"fail to inject javascript";
    
    1. 利用""包裹起来,换行
    NSString *b = @"[AppHost] "
        "It is called \"jsbridge\"."
        "like window.ah('ready') = function(){};"
        "fail to inject javascript";
    
    1. 最最常见的 \ 号分隔,保留缩进(注意观察截图里的 linenum 和代码的距离

      \分隔符,保留缩进
    2. 最最常见的 \ 号分隔,不保留缩进(注意观察截图里的 linenum 和代码的距离

      \分隔符,不保留缩进
    3. 非多行

    NSString *d = @"[AppHost] It is called \"jsbridge\".like window.ah('ready') = function(){};fail to inject javascript";
    

    输出结果

    结果

    可见,对于 a\b\c1\d 变量的值而言等价的。对 c,有个陷阱:实际上获得的字符串是包含编辑器缩进。我们现在基本都会让编辑器自动缩进代码,所以容易出错。

    上面 4 种写法,都需要处理字符" 引号嵌套的问题,或者需要手动加 " 号,或手动写 \ 号,要么一行损失掉可读性。
    作者一般用 d 方法:在 vscode 里写好 JavaScript 代码,放在 sublime text 里 先replace("\"","\\\""),然后command+j 合并行,再贴到Xcode 里。直到我发现无意中创建的一个宏完美的解决了这个问题。

    ah_doc_code(window.appHost.invoke('startNewPage', { 'url': 'http://you.163.com/','title': 'title',
        'type': "push",
        'backPageParameter': {
            'url': 'http://qian.163.com',
            'title': 'title',
            'type': 'push'
        }
    }))
    

    优点

    1. 多行,保存源码中的缩进和换行
    2. 单双引号混排,不需要转义
    3. 使用简单,只需要包含在对()中,甚至都不需要外层加双引号、#号(NSString)
    4. 神似 ruby 中的多行字符串声明(以下代码是 AppHost 里生成自动测试用例的片段) ruby 中的多行字符串

    3. 那个宏 lei 了

    #define ah_ml(str) @#str
    

    🍄简单的令人发指。用例:

    result = [NSString stringWithFormat:ah_ml((function(e){
                    e.setAttribute("src",'%@');
                    document.getElementsByTagName('body')[0].appendChild(e);
                })(document.createElement('script'));), urlToRequest.absoluteString];
    

    查看预处理的代码,代码e.setAttribute("src",'%@');里的引号自动转义。

    result = [NSString stringWithFormat:@"(function(e){ e.setAttribute(\"src\",'%@'); document.getElementsByTagName('body')[0].appendChild(e); })(document.createElement('script'));", urlToRequest.absoluteString];
    

    完美呈现。

    4.注

    1. AppHost.framework 是作者在网易有钱、严选工作中,抽离出来 JSBridge 的库,实现 native 和 h5 之间的通讯,内置诸多常用的功能,在业务简单的情况下可开箱即用,复杂情况允许灵活定制。预计在4月底开源。

    相关文章

      网友评论

        本文标题:objc 中最好的多行字符串声明方式

        本文链接:https://www.haomeiwen.com/subject/exmqgqtx.html