1<!DOCTYPE html> 2<html lang="en"> 3 4<head> 5 <meta charset="utf-8"> 6 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 7 <meta name="google-site-verification" content="xBT4GhYoi5qRD5tr338pgPM5OWHHIDR6mNg1a3euekI" /> 8 <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> 9 <meta name="description" content="Learning... Codeing..."> 10 <meta name="keywords" content="Shown, ShownBie, poos, iOS, Apple, iPhone"> 11 <meta name="theme-color" content="#000000"> 12 13 <!-- Open Graph --> 14 <meta property="og:title" content="Swift Macro å®è·µï¼å°è£ OSLog - Welocme to Shown's blog"> 15 16 <meta property="og:type" content="article"> 17 <meta property="og:description" content=" 18 ä»åºå·²å¼æº:NoLogMacroã 19 20 21"> 22 23 <meta property="article:published_time" content="2024-05-11T00:00:00Z"> 24 25 26 <meta property="article:author" content="poos"> 27 28 29 <meta property="article:tag" content="Swift Macro"> 30 31 <meta property="article:tag" content="Code"> 32 33 34 <meta property="og:image" content="https://poos.github.io/img/about-Me.png"> 35 <meta property="og:url" content="https://poos.github.io/2024/05/11/swiftmacro/"> 36 <meta property="og:site_name" content="Welocme to Shown's blog"> 37 38 <title>Swift Macro å®è·µï¼å°è£ OSLog - Welocme to Shown's blog</title> 39 40 <!-- Web App Manifest --> 41 <link rel="manifest" href="/pwa/manifest.json"> 42 43 <!-- Favicon --> 44 <link rel="shortcut icon" href="/img/favicon.ico"> 45 46 <!-- Canonical URL --> 47 <link rel="canonical" href="https://poos.github.io/2024/05/11/swiftmacro/"> 48 49 <!-- Bootstrap Core CSS --> 50 <link rel="stylesheet" href="/css/bootstrap.min.css"> 51 52 <!-- Custom CSS --> 53 <link rel="stylesheet" href="/css/hux-blog.min.css"> 54 55 <!-- Custom Fonts --> 56 <!-- <link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet" type="text/css"> --> 57 <!-- Hux change font-awesome CDN to qiniu --> 58 <link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" type="text/css"> 59 60 61 <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> 62 <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> 63 <!--[if lt IE 9]> 64
64<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
64 65
65<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
65 66 <![endif]--> 67 68 <!-- ga & ba script hoook --> 69
69<script></script>
69 70</head> 71 72 73<!-- hack iOS CSS :active style --> 74<body ontouchstart=""> 75 76 <!-- Navigation --> 77 78 <nav class="navbar navbar-default navbar-custom navbar-fixed-top"> 79 80 <div class="container-fluid"> 81 <!-- Brand and toggle get grouped for better mobile display --> 82 <div class="navbar-header page-scroll"> 83 <button type="button" class="navbar-toggle"> 84 <span class="sr-only">Toggle navigation</span> 85 <span class="icon-bar"></span> 86 <span class="icon-bar"></span> 87 <span class="icon-bar"></span> 88 </button> 89 <a class="navbar-brand" href="/">Shown's blog</a> 90 </div> 91 92 <!-- Collect the nav links, forms, and other content for toggling --> 93 <div id="huxblog_navbar"> 94 <div class="navbar-collapse"> 95 <ul class="nav navbar-nav navbar-right"> 96 <li> 97 <a href="/">Home</a> 98 </li> 99 100 101 102 103 <li> 104 <a href="/about/">About</a> 105 </li> 106 107 108 109 <li> 110 <a href="/archive/">Archive</a> 111 </li> 112 113 114 115 116 117 118 119 <li> 120 <a href="/offline.html">Offline</a> 121 </li> 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 <li class="search-icon"> 139 <a href="javascript:void(0)"> 140 <i class="fa fa-search"></i> 141 </a> 142 </li> 143 </ul> 144 </div> 145 </div> 146 <!-- /.navbar-collapse --> 147 </div> 148 <!-- /.container --> 149 </nav> 150 151
151<script> 152 // Drop Bootstarp low-performance Navbar 153 // Use customize navbar with high-quality material design animation 154 // in high-perf jank-free CSS3 implementation 155 var $body = document.body; 156 var $toggle = document.querySelector('.navbar-toggle'); 157 var $navbar = document.querySelector('#huxblog_navbar'); 158 var $collapse = document.querySelector('.navbar-collapse'); 159 160 var __HuxNav__ = { 161 close: function () { 162 $navbar.className = " "; 163 // wait until animation end. 164 setTimeout(function () { 165 // prevent frequently toggle 166 if ($navbar.className.indexOf('in') < 0) { 167 $collapse.style.height = "0px" 168 } 169 }, 400) 170 }, 171 open: function () { 172 $collapse.style.height = "auto" 173 $navbar.className += " in"; 174 } 175 } 176 177 // Bind Event 178 $toggle.addEventListener('click', function (e) { 179 if ($navbar.className.indexOf('in') > 0) { 180 __HuxNav__.close() 181 } else { 182 __HuxNav__.open() 183 } 184 }) 185 186 /** 187 * Since Fastclick is used to delegate 'touchstart' globally 188 * to hack 300ms delay in iOS by performing a fake 'click', 189 * Using 'e.stopPropagation' to stop 'touchstart' event from 190 * $toggle/$collapse will break global delegation. 191 * 192 * Instead, we use a 'e.target' filter to prevent handler 193 * added to document close HuxNav. 194 * 195 * Also, we use 'click' instead of 'touchstart' as compromise 196 */ 197 document.addEventListener('click', function (e) { 198 if (e.target == $toggle) return; 199 if (e.target.className == 'icon-bar') return; 200 __HuxNav__.close(); 201 }) 202 </script>
202 203 <!-- Search --> 204<div class="search-page"> 205 <div class="search-icon-close-container"> 206 <span class="search-icon-close"> 207 <i class="fa fa-chevron-down"></i> 208 </span> 209 </div> 210 <div class="search-main container"> 211 <div class="row"> 212 <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1"> 213 <form></form> 214 <input type="text" id="search-input" placeholder="$ grep..."> 215 </form> 216 <div id="search-results" class="mini-post-list"></div> 217 </div> 218 </div> 219 </div> 220</div> 221 222 <!-- Image to hack wechat --> 223<!-- <img src="/img/icon_wechat.png" width="0" height="0"> --> 224<!-- <img src="/img/post-bg-2015.jpg" width="0" height="0"> --> 225 226<!-- Post Header --> 227 228 229 230<style type="text/css"> 231 header.intro-header{ 232 position: relative; 233 background-image: url('/img/post-bg-2015.jpg'); 234 background: ; 235 } 236 237 238</style> 239 240<header class="intro-header" > 241 242 <div class="header-mask"></div> 243 244 <div class="container"> 245 <div class="row"> 246 <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1"> 247 <div class="post-heading"> 248 <div class="tags"> 249 250 <a class="tag" href="/archive/?tag=Swift+Macro" title="Swift Macro">Swift Macro</a> 251 252 <a class="tag" href="/archive/?tag=Code" title="Code">Code</a> 253 254 </div> 255 <h1>Swift Macro å®è·µï¼å°è£ OSLog</h1> 256 257 <h2 class="subheading">Xcode15åï¼debugæ§å¶å°æä¾äºé常æç¨çæ¥å¿è¾å ¥ï¼å ¶ä¸å æ¬äºå¯ç´æ¥å®ä½å°ä»£ç è¡çåè½ãæ¬æçå®è·µè®©æä»¬èªå·±çæ¥å¿åºå¯ä»¥å®ç°ç±»ä¼¼çåè½ã</h2> 258 <span class="meta">Posted by poos on May 11, 2024</span> 259 </div> 260 </div> 261 </div> 262 </div> 263</header> 264 265 266 267 268 269 270<!-- Post Content --> 271<article> 272 <div class="container"> 273 <div class="row"> 274 275 <!-- Post Container --> 276 <div class=" 277 col-lg-8 col-lg-offset-2 278 col-md-10 col-md-offset-1 279 post-container"> 280 281 <!-- Multi-Lingual --> 282 283 284 <blockquote> 285 <p>ä»åºå·²å¼æº:<a href="https://github.com/poos/NoLogMacro">NoLogMacro</a>ã</p> 286</blockquote> 287 288<h1 id="swift-macro">Swift Macro</h1> 289 290<p>Swift Macro æ¯ 2023 WWDC æ¨åºçã对äºSwift Macroçä»ç»æç« ä¸å°ï¼ä½æ¯å¤§é¨å齿¯å®æ¹è§é¢çç¿»è¯ï¼ä¾ååä¸äºé®é¢ä»ç»å¤çççæ¯æ¯è¾å°ãæ¬æè¿ççæå¯è½æ¯ç¬¬ä¸ä¸ªå®è·µåºç¨çâ¦</p> 291 292<h2 id="ç¹ç¹">ç¹ç¹</h2> 293 294<p>ç®åäºè§£ WWDC https://developer.apple.com/videos/play/wwdc2023/10166/ åï¼åºè¯¥è½å¾åºä¸ä¸ç»è®ºï¼</p> 295 296<p>Swfit Macro 大æ¦å两ç§ï¼è¡¨è¾¾å¼å®ï¼#ï¼ï¼åæ©å±å®ï¼@ï¼ãè¿ä¹ä¸æ³éå¶è¿çå¤ï¼ä½æ¯ä¿è¯äºswift macroçå®å ¨æ§ï¼å°±æ¯è¯´å®æ¯æç±»åå¤æï¼æ³åçã</p> 297 298<h1 id="swift-macro-å-oslog-ç-碰æ">Swift Macro å OSLog ç 碰æ</h1> 299 300<p>Xcode15åï¼debugæ§å¶å°æä¾äºé常æç¨çæ¥å¿è¾å ¥ï¼å ¶ä¸å æ¬äºå¯ç´æ¥å®ä½å°ä»£ç è¡çåè½ã</p> 301 302<p>åè§ä¾¿æ³å°ï¼å¦ææä»¬èªå·±çæ¥å¿åºè½å¤å®ç°ç¸åºçåè½ï¼é£è°è¯bug䏿¯æå°ææ¥ã</p> 303 304<p>è¦æ¯æçåè½å¾ç®åï¼</p> 305<ul> 306 <li>æ¯ææ¥å¿ï¼è½¬åå°èªå·±çæ¥å¿åºå¤ç</li> 307 <li>æ¯æä»£ç è¡å®ä½</li> 308</ul> 309 310<p>å±å°±æ¯è¯´ï¼æä¸ªç»ä¸çæ¶æ¯è½¬åï¼ç¶åå¨ä½¿ç¨å®è¿è¡OSLogå¤çï¼æä¸¤ä¸ªè¡¨è¾¾å¼ç¨å®å®ä¹ï¼å¦æéªè¯ä»£ç è¡è½æ£ç¡®å®ä½å³å¯ã</p> 311 312<p>é¢éªè¯ç¡®å®è½æ£ç¡®å®ä½å°ä»£ç è¡ï¼é£ä¹å¯ä»¥å¼å¹²äºã</p> 313 314<h2 id="ç«è±1ä» æ¯æåè¡è¡¨è¾¾å¼">ç«è±1ï¼ä» æ¯æåè¡è¡¨è¾¾å¼</h2> 315 316<p>æ ¹æ®WWDCçææ¡£ï¼æèµ·ï¼</p> 317<ul> 318 <li>项ç®å建</li> 319 <li>å®å®ä¹</li> 320 <li>æµè¯success</li> 321 <li>duangï¼è¿è¡èµ·æ¥æ¥éäº</li> 322</ul> 323 324<p><img src="https://poos.github.io/img/post-swift-macro.png" alt="img" /></p> 325 326<p>
326è¿ä¸ªæ¥é没ææç¨ä¿¡æ¯ï¼å¿½ç¶æ³å°è¡¨è¾¾å¼å¯ä»¥ç¨äºåå§ååéï¼æ¯ä¸æ¯æå¯è½ä¸æ¯æå¤ä¸ªè¡¨è¾¾å¼ï¼éè¿ä¿®æ¹å®ï¼å§ç»ä¸è½æ£ç¡®ç¼è¯ã</p> 327 328<p>æ¢ç¶<strong>Swift 表达å¼å®ä¸æ¯æå¤ä¸ªè¡¨è¾¾å¼</strong>ï¼é£ä¹å°±ç¨åè¡è¡¨è¾¾å¼å§ã</p> 329 330<h1 id="ç«è±2䏿¯æéå ">ç«è±2ï¼ä¸æ¯æéå </h1> 331 332<p>éè¿ä½¿ç¨éå ï¼è¿æ ·å°±è½æ§è¡æ¹æ³ï¼ç¶ååéå é颿§è¡logæ¶å½æè è°ç¨ç³»ç»logå³å¯ã</p> 333 334<p>æ¹å¼1:</p> 335<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1 3362 3373 3384 3395 340</pre></td><td class="rouge-code"><pre>Logger() 341.sync { 342 NoLog.noLog("msg", attrs: ["a": 1]) 343} 344.log("msg") 345</pre></td></tr></tbody></table></code></pre></div></div> 346<p>å¯ä»¥æ£ç¡®å®ä½å°ä»£ç è¡ï¼<strong>使¯ï¼NoLogæ¶æ¯ä¸å¿æ¶å°çæ¶æ¯å§ç»æ¯ç¬¬ä¸ä¸ª</strong>ã 347æ¹å¼2:</p> 348 349<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1 3502 3513 3524 3535 354</pre></td><td class="rouge-code"><pre>NoLog 355.sync { 356 Logger().log("msg") 357} 358.noLog("msg", attrs: ["a": 1]) 359</pre></td></tr></tbody></table></code></pre></div></div> 360<p><strong>ä¸è½æ£ç¡®å®ä½å°ä»£ç è¡</strong>ï¼NoLogæ¶æ¯ä¸å¿æ¶å°çæ£ç¡®ã</p> 361 362<p>è¿ä¸éå çè·¯å µæ»äºãçæµåºè¯¥æ¯å®å±å¼ï¼block被è§ä¸ºå¸¸éï¼æç»å±å¼æ¶åç¸å½äºä¸ä¸ªå ¨å±çblockã</p> 363 364<h2 id="é¾å¼è¯æ³">é¾å¼è¯æ³</h2> 365<p>æ¡æ¡å¤§è·¯ï¼é£ä¹è¯è¯é¾å¼è¯æ³ççï¼</p> 366<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1 3672 3683 369</pre></td><td class="rouge-code"><pre>Logger() 370.noLog("msg", attrs: ["a": 1]) 371.log("msg") 372</pre></td></tr></tbody></table></code></pre></div></div> 373<p>è¿æ¯è¿ä¸ªæ¹æ³okï¼æ¢è½å¤æ¾ç¤ºå°ä»£ç è¡ï¼ä¹è½å°æ¶æ¯ä¸å¿æåºæ¥å¿ãå©ä¸çå°±å©ä¸å°è£ å®äºãæç §ææ¡£ä¸æ¥æ¥æ¥å³å¯ã</p> 374 375<p>飿åï¼ç®åçä¸ OC define å Swfit Macro çåºå«ï¼</p> 376 377<table> 378 <thead> 379 <tr> 380 <th>·</th> 381 <th>OC define</th> 382 <th>Swfit Macro</th> 383 </tr> 384 </thead> 385 <tbody> 386 <tr> 387 <td>代ç ç¼è¾å¨ç±»åæ£æµ</td> 388 <td>N</td> 389 <td>Y</td> 390 </tr> 391 <tr> 392 <td>å®ä¹å个表达å¼</td> 393 <td>Y</td> 394 <td>Y</td> 395 </tr> 396 <tr> 397 <td>å®ä¹å¤ä¸ªè¡¨è¾¾å¼</td> 398 <td>Y</td> 399 <td>N</td> 400 </tr> 401 <tr> 402 <td>å®ä¹åç§ç»æçæ©å±</td> 403 <td>Y</td> 404 <td>Y</td> 405 </tr> 406 </tbody> 407</table> 408 409<p>ä¹å°±æ¯è¯´ï¼Swift Macro å¨ä¿è¯ç±»åå®å ¨çæ åµä¸ï¼æ¯æå个表达å¼åæ°æ®ç»æçå®ã</p> 410 411<h1 id="弿ºåº">弿ºåº</h1> 412 413<p><strong><a href="https://github.com/poos/NoLogMacro">Not Only Log</a></strong>ï¼ï¼çµææ¥èªnosqlï¼ï¼æ¯è¾è´´åçææ¨æã</p> 414 415<p><strong>å çææï¼å¸¸è§æ¹æ³çlogæ æ³å®ä½å°æ£ç¡®ç代ç è¡ãéè¿æ¬åºæä¾ç宿¹æ³å¯ä»¥å®ç¾ç以å®çæ¹å¼æ¯æï¼é常轻é级ã</strong></p> 416 417<p><img src="https://poos.github.io/img/post-swift-macro2.gif" alt="img" /></p> 418 419<h2 id="使ç¨">使ç¨</h2> 420<p>åºå·²å¼æºã使ç¨ç¸å½ç®åï¼ä½æ¯èèå°å¾å¤å°ä¼ä¼´æ²¡ä½¿ç¨è¿ swift packageï¼ç¹å«å½å¶äºä¸äºæ¥éª¤ï¼</p> 421 422<ul> 423 <li>å³é®æ·»å Packageï¼éè¿é¾æ¥ <code class="language-plaintext highlighter-rouge">https://github.com/poos/NoLogMacro</code> æ·»å ï¼åæ¶éæ© Lib å Client</li> 424 <li><code class="language-plaintext highlighter-rouge">import OSLog</code> å <code class="language-plaintext highlighter-rouge">import NoLogMacro</code>ï¼åå§å <code class="language-plaintext highlighter-rouge">NoLogger.callback</code>ï¼å¯éï¼</li> 425 <li>使ç¨<code class="language-plaintext highlighter-rouge">#noLog()</code> ä»£æ¿ <code class="language-plaintext highlighter-rouge">Logger().log()</code></li> 426</ul> 427 428<p>gif:</p> 429 430<p><img src="https://poos.github.io/img/post-swift-macro3.gif" alt="img" /></p> 431 432<h3 id="code">Code</h3> 433 434<p>
434å ·ä½ä»£ç ï¼ä¸å ±å°±å è¡ï¼èµ·é£:</p> 435 436<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1 4372 4383 4394 4405 4416 4427 4438 4449 44510 44611 44712 44813 44914 45015 45116 45217 45318 45419 45520 45621 45722 45823 45924 46025 46126 46227 46328 46429 46530 46631 46732 46833 46934 470</pre></td><td class="rouge-code"><pre>//import 471import OSLog 472import NoLogMacro 473 474// set once 475NoLogger.callback = { (type: OSLogType, message: String, attrs: Dictionary<String, Any>?) in 476 print("simple type: \(type) message: \(message) dic: \(String(describing: attrs))") 477} 478 479 480// all log can send to `NoLogger.callback` 481// **can be located to a line** 482 483// same with `Logger().log(level: .default, "default")` 484#noLog("message") 485// and more custom info 486#noLogError("error", attrs: ["code": 404]) 487 488// others 489Logger().log(level: .info, "info") 490#noLogInfo("info") 491#noLogInfo("info", attrs: ["a": 2]) 492 493Logger().log(level: .debug, "debug") 494#noLogDebug("debug") 495#noLogDebug("debug", attrs: ["a": 3]) 496 497Logger().log(level: .error, "error") 498#noLogError("error") 499#noLogError("error", attrs: ["a": 4]) 500 501Logger().log(level: .fault, "fault") 502#noLogFault("fault") 503#noLogFault("fault", attrs: ["a": 5]) 504</pre></td></tr></tbody></table></code></pre></div></div> 505 506<h2 id="todo-list">TODO List</h2> 507 508<p>å½ç¶è¿æå 个TODO项ï¼just waiting ä¸ä¸åã</p> 509 510<ul> 511 <li>support <code class="language-plaintext highlighter-rouge">Logger(subsystem: <#T##String#>, category: <#T##String#>)</code></li> 512 <li>brew iOS 14, using print support</li> 513 <li>using Swift Macro writing this lib</li> 514</ul> 515 516 517 <hr style="visibility: hidden;"> 518 <ul class="pager"> 519 520 <li class="previous"> 521 <a href="/2024/03/30/apm_launch_time/" data-toggle="tooltip" data-placement="top" title="ä¼åappå¯å¨"> 522 Previous<br> 523 <span>ä¼åappå¯å¨</span> 524 </a> 525 </li> 526 527 528 </ul> 529 <hr style="visibility: hidden;"> 530 531 532 <!-- disqus è¯è®ºæ¡ start --> 533 <div class="comment"> 534 <div id="disqus_thread" class="disqus-thread"></div> 535 </div> 536 <!-- disqus è¯è®ºæ¡ end --> 537 538 539 540 </div> 541 542 <!-- Side Catalog Container --> 543 544 <div class=" 545 col-lg-2 col-lg-offset-0 546 visible-lg-block 547 sidebar-container 548 catalog-container"> 549 <div class="side-catalog"> 550 <hr class="hidden-sm hidden-xs"> 551 <h5> 552 <a class="catalog-toggle" href="#">CATALOG</a> 553 </h5> 554 <ul class="catalog-body"></ul> 555 </div> 556 </div> 557 558 559 <!-- Sidebar Container --> 560 <div class=" 561 col-lg-8 col-lg-offset-2 562 col-md-10 col-md-offset-1 563 sidebar-container"> 564 565 <!-- Featured Tags --> 566 567 568 569<section> 570 571 <hr class="hidden-sm hidden-xs"> 572 573 <h5><a href="/archive/">FEATURED TAGS</a></h5> 574 <div class="tags"> 575 576 577 578 579 580 581 <a data-sort="0078" 582 href="/archive/?tag=Note" 583 title="Note" 584 rel="4">Note</a> 585 586 <a data-sort="0047" 587 href="/archive/?tag=Summary" 588 title="Summary" 589 rel="35">Summary</a> 590 591 <a data-sort="0053" 592 href="/archive/?tag=Code" 593 title="Code" 594 rel="29">Code</a> 595 596 <a data-sort="0067" 597 href="/archive/?tag=Design" 598 title="Design" 599 rel="15">Design</a> 600 601 <a data-sort="0071" 602 href="/archive/?tag=Linter" 603 title="Linter" 604 rel="11">Linter</a> 605 606 <a data-sort="0075" 607 href="/archive/?tag=Flutter" 608 title="Flutter" 609 rel="7">Flutter</a> 610 611 <a data-sort="0076" 612 href="/archive/?tag=APM" 613 title="APM" 614 rel="6">APM</a> 615 616 <a data-sort="0076" 617 href="/archive/?tag=Book" 618 title="Book" 619 rel="6">Book</a> 620 621 <a data-sort="0076" 622 href="/archive/?tag=Module" 623 title="Module" 624 rel="6">Module</a> 625 626 <a data-sort="0077" 627 href="/archive/?tag=Debug" 628 title="Debug" 629 rel="5">Debug</a> 630 631 <a data-sort="0077" 632 href="/archive/?tag=Easter+eggs" 633 title="Easter eggs" 634 rel="5">Easter eggs</a> 635 636 <a data-sort="0077" 637 href="/archive/?tag=Improve" 638 title="Improve" 639 rel="5">Improve</a> 640 641 <a data-sort="0077" 642 href="/archive/?tag=Knowledge" 643 title="Knowledge" 644 rel="5">Knowledge</a> 645 646 <a data-sort="0077" 647 href="/archive/?tag=Repo" 648 title="Repo" 649 rel="5">Repo</a> 650 651 <a data-sort="0078" 652 href="/archive/?tag=Script" 653 title="Script" 654 rel="4">Script</a> 655 656 <a data-sort="0078" 657 href="/archive/?tag=Tool" 658 title="Tool" 659 rel="4">Tool</a> 660 661 <a data-sort="0079" 662 href="/archive/?tag=CICD" 663 title="CICD" 664 rel="3">CICD</a> 665 666 <a data-sort="0079" 667 href="/archive/?tag=Objective-C" 668 title="Objective-C" 669 rel="3">Objective-C</a> 670 671 <a data-sort="0079" 672 href="/archive/?tag=RxSwift" 673 title="RxSwift" 674 rel="3">RxSwift</a> 675 676 <a data-sort="0079" 677 href="/archive/?tag=Storyboard" 678 title="Storyboard" 679 rel="3">Storyboard</a> 680 681 <a data-sort="0079" 682 href="/archive/?tag=Swifter+Tips" 683 title="Swifter Tips" 684 rel="3">Swifter Tips</a> 685 686 <a data-sort="0079" 687 href="/archive/?tag=Texture" 688 title="Texture" 689 rel="3">Texture</a> 690 691 <a data-sort="0079" 692 href="/archive/?tag=Toolchain" 693 title="Toolchain" 694 rel="3">Toolchain</a> 695 696 <a data-sort="0080" 697 href="/archive/?tag=Algorithm" 698 title="Algorithm" 699 rel="2">Algorithm</a> 700 701 <a data-sort="0080" 702 href="/archive/?tag=Functional+Programming" 703 title="Functional Programming" 704 rel="2">Functional Programming</a> 705 706 <a data-sort="0080" 707 href="/archive/?tag=Project" 708 title="Project" 709 rel="2">Project</a> 710 </div> 711</section> 712 713 714 <!-- Friends Blog --> 715 716<hr> 717<h5>FRIENDS</h5> 718<ul class="list-inline"> 719 720 <li><a href="https://github.com/poos">github/poos</a></li> 721 722 <li><a href="https://gitee.com/poos">gitee/poos</a></li> 723 724 <li><a href="https://my.oschina.net/bieshixuan">oschina/bieshixuan</a></li> 725 726</ul> 727 728 </div> 729 </div> 730 </div> 731</article> 732 733<!-- add support for mathjax by voleking--> 734 735 736 737 738 739 740<!-- disqus å ¬å ±JS代ç start (ä¸ä¸ªç½é¡µåªéæå ¥ä¸æ¬¡) -->
741<script type="text/javascript"> 742 /* * * CONFIGURATION VARIABLES * * */ 743 var disqus_shortname = "poos"; 744 var disqus_identifier = "/2024/05/11/swiftmacro"; 745 var disqus_url = "https://poos.github.io/2024/05/11/swiftmacro/"; 746 747 (function() { 748 var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true; 749 dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js'; 750 (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq); 751 })(); 752</script>
752 753<!-- disqus å ¬å ±JS代ç end --> 754 755 756 757 758<!-- async load function -->
759<script> 760 function async(u, c) { 761 var d = document, t = 'script', 762 o = d.createElement(t), 763 s = d.getElementsByTagName(t)[0]; 764 o.src = u; 765 if (c) { o.addEventListener('load', function (e) { c(null, e); }, false); } 766 s.parentNode.insertBefore(o, s); 767 } 768</script>
768 769<!-- anchor-js, Doc:http://bryanbraun.github.io/anchorjs/ -->
770<script> 771 async("//cdnjs.cloudflare.com/ajax/libs/anchor-js/1.1.1/anchor.min.js",function(){ 772 anchors.options = { 773 visible: 'hover', 774 placement: 'right', 775 // icon: '#' 776 }; 777 anchors.add().remove('.intro-header h1').remove('.subheading').remove('.sidebar-container h5'); 778 }) 779</script>
779 780<style> 781 /* place left on bigger screen */ 782 @media all and (min-width: 800px) { 783 .anchorjs-link{ 784 position: absolute; 785 left: -0.75em; 786 font-size: 1.1em; 787 margin-top : -0.1em; 788 } 789 } 790</style> 791 792 793 794 <!-- Footer --> 795<footer> 796 <div class="container"> 797 <div class="row"> 798 <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1"> 799 <!-- SNS Link --> 800 801 802 803<ul class="list-inline text-center"> 804 805 806 807 808 809 810 <li> 811 <a target="_blank" href="http://weibo.com/poos_github.io"> 812 <span class="fa-stack fa-lg"> 813 <i class="fa fa-circle fa-stack-2x"></i> 814 <i class="fa fa-weibo fa-stack-1x fa-inverse"></i> 815 </span> 816 </a> 817 </li> 818 819 820 821 <li> 822 <a target="_blank" href="https://github.com/poos"> 823 <span class="fa-stack fa-lg"> 824 <i class="fa fa-circle fa-stack-2x"></i> 825 <i class="fa fa-github fa-stack-1x fa-inverse"></i> 826 </span> 827 </a> 828 </li> 829 830 831</ul> 832 833 <p class="copyright text-muted"> 834 Copyright © Shown's blog 2024 835 <br> 836 Powered by <a href="https://github.com/poos/poos.github.io">Shixuan'S Blog</a> | 837 <iframe 838 style="margin-left: 2px; margin-bottom:-5px;" 839 frameborder="0" scrolling="0" width="100px" height="20px" 840 src="https://ghbtns.com/github-btn.html?user=poos&repo=poos.github.io&type=star&count=true" > 841 </iframe> 842 </p> 843 </div> 844 </div> 845 </div> 846</footer> 847 848<!-- jQuery -->
849<script src="/js/jquery.min.js "></script>
849 850 851<!-- Bootstrap Core JavaScript --> 852<!-- Currently, only navbar scroll-down effect at desktop still depends on this -->
853<script src="/js/bootstrap.min.js "></script>
853 854 855<!-- Custom Theme JavaScript -->
856<script src="/js/hux-blog.min.js "></script>
856 857 858<!-- Simple Jekyll Search -->
859<script src="/js/simple-jekyll-search.min.js"></script>
859 860 861<!-- Service Worker --> 862
863<script src="/js/snackbar.js "></script>
vendor: 1 bytes, line 863
863
864<script src="/js/sw-registration.js "></script>
864 865 866 867<!-- async load function -->
868<script> 869 function async(u, c) { 870 var d = document, t = 'script', 871 o = d.createElement(t), 872 s = d.getElementsByTagName(t)[0]; 873 o.src = u; 874 if (c) { o.addEventListener('load', function (e) { c(null, e); }, false); } 875 s.parentNode.insertBefore(o, s); 876 } 877</script>
877 878 879<!-- 880 Because of the native support for backtick-style fenced code blocks 881 right within the Markdown is landed in Github Pages, 882 From V1.6, There is no need for Highlight.js, 883 so Huxblog drops it officially. 884 885 - https://github.com/blog/2100-github-pages-now-faster-and-simpler-with-jekyll-3-0 886 - https://help.github.com/articles/creating-and-highlighting-code-blocks/ 887 - https://github.com/jneen/rouge/wiki/list-of-supported-languages-and-lexers 888--> 889<!-- 890
890<script> 891 async("http://cdn.bootcss.com/highlight.js/8.6/highlight.min.js", function(){ 892 hljs.initHighlightingOnLoad(); 893 }) 894 </script>
894 895 <link href="http://cdn.bootcss.com/highlight.js/8.6/styles/github.min.css" rel="stylesheet"> 896--> 897 898 899 900 901 902 903 904<!--fastClick.js -->
905<script> 906 async("//cdnjs.cloudflare.com/ajax/libs/fastclick/1.0.6/fastclick.min.js", function () { 907 var $nav = document.querySelector("nav"); 908 if ($nav) FastClick.attach($nav); 909 }) 910</script>
910 911 912 913<!-- Google Analytics --> 914 915 916 917<!-- Baidu Tongji --> 918 919 920 921<!-- Side Catalog --> 922
923<script type="text/javascript"> 924 function generateCatalog(selector) { 925 926 // interop with multilangual 927 if ('' == 'true') { 928 _containerSelector = 'div.post-container.active' 929 } else { 930 _containerSelector = 'div.post-container' 931 } 932 933 // init 934 var P = $(_containerSelector), a, n, t, l, i, c; 935 a = P.find('h1,h2,h3,h4,h5,h6'); 936 937 // clean 938 $(selector).html('') 939 940 // appending 941 a.each(function () { 942 n = $(this).prop('tagName').toLowerCase(); 943 i = "#" + $(this).prop('id'); 944 t = $(this).text(); 945 c = $('<a href="' + i + '" rel="nofollow">' + t + '</a>'); 946 l = $('<li class="' + n + '_nav"></li>').append(c); 947 $(selector).append(l); 948 }); 949 return true; 950 } 951 952 generateCatalog(".catalog-body"); 953 954 // toggle side catalog 955 $(".catalog-toggle").click((function (e) { 956 e.preventDefault(); 957 $('.side-catalog').toggleClass("fold") 958 })) 959 960 /* 961 * Doc: https://github.com/davist11/jQuery-One-Page-Nav 962 * Fork by Hux to support padding 963 */ 964 async("/js/jquery.nav.js", function () { 965 $('.catalog-body').onePageNav({ 966 currentClass: "active", 967 changeHash: !1, 968 easing: "swing", 969 filter: "", 970 scrollSpeed: 700, 971 scrollOffset: 0, 972 scrollThreshold: .2, 973 begin: null, 974 end: null, 975 scrollChange: null, 976 padding: 80 977 }); 978 }); 979</script>
979 980 981 982 983<!-- Multi-Lingual --> 984 985 986<!-- Simple Jekyll Search -->
987<script> 988 // https://stackoverflow.com/questions/1912501/unescape-html-entities-in-javascript 989 function htmlDecode(input) { 990 var e = document.createElement('textarea'); 991 e.innerHTML = input; 992 // handle case of empty input 993 return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue; 994 } 995 996 SimpleJekyllSearch({ 997 searchInput: document.getElementById('search-input'), 998 resultsContainer: document.getElementById('search-results'), 999 json: '/search.json', 1000 searchResultTemplate: '<div class="post-preview item"><a href="{url}"><h2 class="post-title">{title}</h2><h3 class="post-subtitle">{subtitle}</h3><hr></a></div>', 1001 noResultsText: 'No results', 1002 limit: 50, 1003 fuzzy: false, 1004 // a hack to get escaped subtitle unescaped. for some reason, 1005 // post.subtitle w/o escape filter nuke entire search. 1006 templateMiddleware: function (prop, value, template) { 1007 if (prop === 'subtitle' || prop === 'title') { 1008 if (value.indexOf("code")) { 1009 return htmlDecode(value); 1010 } else { 1011 return value; 1012 } 1013 } 1014 } 1015 }); 1016 1017 $(document).ready(function () { 1018 var $searchPage = $('.search-page'); 1019 var $searchOpen = $('.search-icon'); 1020 var $searchClose = $('.search-icon-close'); 1021 var $searchInput = $('#search-input'); 1022 var $body = $('body'); 1023 1024 $searchOpen.on('click', function (e) { 1025 e.preventDefault(); 1026 $searchPage.toggleClass('search-active'); 1027 var prevClasses = $body.attr('class') || ''; 1028 setTimeout(function () { 1029 $body.addClass('no-scroll'); 1030 }, 400) 1031 1032 if ($searchPage.hasClass('search-active')) { 1033 $searchClose.on('click', function (e) { 1034 e.preventDefault(); 1035 $searchPage.removeClass('search-active'); 1036 $body.attr('class', prevClasses); // from closure 1037 }); 1038 $searchInput.focus(); 1039 } 1040 }); 1041 }); 1042</script>
1042 1043 1044 1045<!-- Image to hack wechat --> 1046<img src="/img/icon_wechat.png" width="0" height="0" /> 1047<!-- Migrate from head to bottom, no longer block render and still work --> 1048 1049</body> 1050 1051</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.