c语言 宏 多行字符串,objc 中最好的多行字符串声明方式

本文探讨了在Objective-C中处理多行字符串的挑战,包括JavaScript代码的嵌入和保持可读性。作者分享了一种巧妙的宏定义方法,通过`ah_ml`宏实现多行字符串的无缝集成,同时保留源码的缩进和换行,避免了引号和转义字符的问题。这种方法在处理复杂的JavaScript注入和多行字符串声明时特别有用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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.常见多行声明方式

利用@""包裹起来,换行

NSString *a = @"[AppHost] "

@"It is called \"jsbridge\"."

@"like window.ah('ready') = function(){};"

@"fail to inject javascript";

利用""包裹起来,换行

NSString *b = @"[AppHost] "

"It is called \"jsbridge\"."

"like window.ah('ready') = function(){};"

"fail to inject javascript";

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

44eaf9839b01?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

\分隔符,保留缩进

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

44eaf9839b01?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

\分隔符,不保留缩进

非多行

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

输出结果

44eaf9839b01?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

结果

可见,对于 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'

}

}))

优点

多行,保存源码中的缩进和换行

单双引号混排,不需要转义

使用简单,只需要包含在对()中,甚至都不需要外层加双引号、#号(NSString)

神似 ruby 中的多行字符串声明(以下代码是 AppHost 里生成自动测试用例的片段)

44eaf9839b01?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

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.注

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值