ios - 在保持向后兼容性的同时采用 os_log API
<p><p>我正在尝试向库中添加对新日志记录和事件跟踪 API 的支持,以便为尚未采用最新版本操作系统(iOS 或 macOS)的库用户保持向后兼容性.我正在为每个级别的日志记录定义自定义日志记录宏,然后为旧操作系统定义回退到 <code>NSLog</code>。我已经完成了这项工作,但有一个问题。</p>
<p>如果您希望它们显示在日志输出中,新 API 要求您将任何非常量、非标量值显式标记为 <code>public</code>。这就是我的宏调用的样子:</p>
<pre><code>UZKLogInfo("Reading file %{public}@ from archive", fileName);
</code></pre>
<p>使用包含 <code>os_log</code> 的 SDK(例如 iOS 10.0 或更高版本)可以正常编译,但是当我使用早期版本编译时,我的宏会退回到 <code>NSLog</code>,我收到编译器警告:</p>
<blockquote>
<p>Using 'public' format specifier annotation outside of os_log()/os_trace()</p>
</blockquote>
<p>打印出来的日志是这样的:</p>
<pre><code>Reading file <decode: missing data> from archive
</code></pre>
<p>这是我的宏定义的简化版(只包括<code>info</code>定义和简化条件:</p>
<pre><code>#if UNIFIED_LOGGING_SUPPORTED
@import os.log;
#define UZKLogInfo(format, ...) os_log_info(OS_LOG_DEFAULT, format, ##__VA_ARGS__);
#else // Fall back to regular NSLog
#define UZKLogInfo(format, ...) NSLog(@format, ##__VA_ARGS__);
#endif
</code></pre>
<p>有没有办法在后备情况下从 <code>format</code> 中去除“{public}”文本(某种字符串替换?)?或者是否有另一种方法来支持新旧 API 而不会放弃我一直在日志中显示的信息级别?我需要使用宏(根据 <a href="https://developer.apple.com/videos/play/wwdc2016/721/" rel="noreferrer noopener nofollow">last year's WWDC session on the topic</a> ,否则我会丢失调用站点元数据。</p></p>
<br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
<p><p>我选择在宏中进行 <code>NSString</code> 替换,并将编译器警告作为其中的一部分进行替换,因此可以针对每一行执行此操作,而不是针对整个文件或项目全局执行此操作.它看起来像这样:</p>
<pre><code>#if UNIFIED_LOGGING_SUPPORTED
@import os.log;
#define UZKLogInfo(format, ...) os_log_info(OS_LOG_DEFAULT, format, ##__VA_ARGS__);
#else // Fall back to regular NSLog
#define _removeLogFormatTokens(format) [@format stringByReplacingOccurrencesOfString:@"{public}" withString:@""]
#define _stringify(a) #a
#define _nsLogWithoutWarnings(format, ...) \
_Pragma( _stringify( clang diagnostic push ) ) \
_Pragma( _stringify( clang diagnostic ignored "-Wformat-nonliteral" ) ) \
_Pragma( _stringify( clang diagnostic ignored "-Wformat-security" ) ) \
NSLog(_removeLogFormatTokens(format), ##__VA_ARGS__); \
_Pragma( _stringify( clang diagnostic pop ) )
#define UZKLogInfo(format, ...) _nsLogWithoutWarnings(format, ##__VA_ARGS__);
#endif
</code></pre>
<p>它是这样称呼的:</p>
<pre><code>UZKLogInfo("Message: %@", anObjectToLog);
</code></pre></p>
<p style="font-size: 20px;">关于ios - 在保持向后兼容性的同时采用 os_log API,我们在Stack Overflow上找到一个类似的问题:
<a href="https://stackoverflow.com/questions/45022233/" rel="noreferrer noopener nofollow" style="color: red;">
https://stackoverflow.com/questions/45022233/
</a>
</p>
页:
[1]