-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
1860 lines (774 loc) · 80.6 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!doctype html>
<html class="theme-next pisces use-motion" lang="zh-Hans">
<head>
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
<link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />
<link href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />
<link href="/css/main.css?v=5.1.0" rel="stylesheet" type="text/css" />
<meta name="keywords" content="Hexo, NexT" />
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico?v=5.1.0" />
<meta property="og:type" content="website">
<meta property="og:title" content="三味猪屋">
<meta property="og:url" content="http://yoursite.com/index.html">
<meta property="og:site_name" content="三味猪屋">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="三味猪屋">
<script type="text/javascript" id="hexo.configurations">
var NexT = window.NexT || {};
var CONFIG = {
root: '/',
scheme: 'Pisces',
sidebar: {"position":"left","display":"post"},
fancybox: true,
motion: true,
duoshuo: {
userId: '0',
author: '博主'
},
algolia: {
applicationID: '',
apiKey: '',
indexName: '',
hits: {"per_page":10},
labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
}
};
</script>
<link rel="canonical" href="http://yoursite.com/"/>
<title> 三味猪屋 </title>
</head>
<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">
<div class="container one-collumn sidebar-position-left
page-home
">
<div class="headband"></div>
<header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
<div class="header-inner"><div class="site-meta ">
<div class="custom-logo-site-title">
<a href="/" class="brand" rel="start">
<span class="logo-line-before"><i></i></span>
<span class="site-title">三味猪屋</span>
<span class="logo-line-after"><i></i></span>
</a>
</div>
<p class="site-subtitle"></p>
</div>
<div class="site-nav-toggle">
<button>
<span class="btn-bar"></span>
<span class="btn-bar"></span>
<span class="btn-bar"></span>
</button>
</div>
<nav class="site-nav">
<ul id="menu" class="menu">
<li class="menu-item menu-item-home">
<a href="/archives" rel="section">
<i class="menu-item-icon fa fa-fw fa-home"></i> <br />
首页
</a>
</li>
<li class="menu-item menu-item-categories">
<a href="/categories" rel="section">
<i class="menu-item-icon fa fa-fw fa-th"></i> <br />
分类
</a>
</li>
<li class="menu-item menu-item-about">
<a href="/about" rel="section">
<i class="menu-item-icon fa fa-fw fa-user"></i> <br />
关于
</a>
</li>
<li class="menu-item menu-item-archives">
<a href="/archives" rel="section">
<i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
归档
</a>
</li>
<li class="menu-item menu-item-tags">
<a href="/tags" rel="section">
<i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
标签
</a>
</li>
</ul>
</nav>
</div>
</header>
<main id="main" class="main">
<div class="main-inner">
<div class="content-wrap">
<div id="content" class="content">
<section id="posts" class="posts-expand">
<article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
<link itemprop="mainEntityOfPage" href="http://yoursite.com/2017/06/14/20170614/">
<span style="display:none" itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="花生-sniper">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.jpg">
</span>
<span style="display:none" itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="三味猪屋">
<span style="display:none" itemprop="logo" itemscope itemtype="http://schema.org/ImageObject">
<img style="display:none;" itemprop="url image" alt="三味猪屋" src="">
</span>
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2017/06/14/20170614/" itemprop="url">
消除第三方library警告
</a>
</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="Post created" itemprop="dateCreated datePublished" datetime="2017-06-14T16:41:18+08:00">
2017-06-14
</time>
</span>
<span class="post-category" >
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/clang/" itemprop="url" rel="index">
<span itemprop="name">clang</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<script src="/assets/js/DPlayer.min.js"> </script><script src="/assets/js/APlayer.min.js"> </script><p>集成第三方库的时候经常会报一些警告,如:<br>1、<code>unable to open object file: No such file or directory</code><br><img src="/images/20170614/warning_1.png" alt=""><br>因为在build静态lib时,CLANG_ENABLE_MODULES没有被设置成NO。<br><img src="/images/20170614/clang_enable_modules.png" alt=""><br>解决办法:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">1) Go to Build Settings -> Build Options -> Debug Information Format</div><div class="line">2) Change the Debug setting from "DWARF with dSYM File" to "DWARF"</div><div class="line">3) Leave the Release setting at "DWARF with dSYM File"</div></pre></td></tr></table></figure></p>
<p>但是这不是根本解决办法,根本的还是需要静态库提供者去消除这个警告。</p>
<p>2、<code>ld: pointer not aligned at address 0x13735E9</code><br><img src="/images/20170614/warning_2.png" alt=""><br><img src="/images/20170614/warning_2_1.jpg" alt=""><br>解决办法:<br><img src="/images/20170614/warning_2_solution.png" alt=""></p>
<p>参考:<br><a href="https://pewpewthespells.com/blog/buildsettings.html#clang_enable_modules" target="_blank" rel="external">https://pewpewthespells.com/blog/buildsettings.html#clang_enable_modules</a><br><a href="https://stackoverflow.com/questions/42268117/how-to-remove-the-xcode-warning-apple-mach-o-linker-warning-pointer-not-aligned/43056194#43056194" target="_blank" rel="external">https://stackoverflow.com/questions/42268117/how-to-remove-the-xcode-warning-apple-mach-o-linker-warning-pointer-not-aligned/43056194#43056194</a></p>
</div>
<div>
</div>
<div>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
<link itemprop="mainEntityOfPage" href="http://yoursite.com/2017/06/02/20170603/">
<span style="display:none" itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="花生-sniper">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.jpg">
</span>
<span style="display:none" itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="三味猪屋">
<span style="display:none" itemprop="logo" itemscope itemtype="http://schema.org/ImageObject">
<img style="display:none;" itemprop="url image" alt="三味猪屋" src="">
</span>
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2017/06/02/20170603/" itemprop="url">
iOS包大小瘦身方案(二)- 基于clang插件iOS瘦身实践
</a>
</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="Post created" itemprop="dateCreated datePublished" datetime="2017-06-02T08:32:39+08:00">
2017-06-02
</time>
</span>
<span class="post-category" >
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/app-thinning/" itemprop="url" rel="index">
<span itemprop="name">app-thinning</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<script src="/assets/js/DPlayer.min.js"> </script><script src="/assets/js/APlayer.min.js"> </script><p>clang作为LLVM提供的编译器前端,可将用户的源代码(C/C++/Objective-C)编译成语言/目标设备无关的IR(Intermediate Representation)实现。其可提供良好的插件支持,容许用户在编译时,运行额外的自定义动作。<br>本篇是基于clang的插件特性,编写一个clang插件作为一个源代码级别的分析工具(或编译器)生成各种中间文件。编译完成后,还需编写一个工具去分析所有包含源码的方法(包括用户编写,以及引入的第三方库源代码),检查这些方法中哪些最终可被程序主入口调用,剩余即是疑似无用代码。从而分析出源代码中那些确定无用的代码,便可以有效去除无用的代码从而减少包大小。<br>LLVM工程包含了一组模块化,可复用的编辑器和工具链:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">LLVM Core:包含一个现在的源代码/目标设备无关的优化器,一集一个针对很多主流(甚至于一些非主流)的CPU的汇编代码生成支持。</div><div class="line">Clang:一个C/C++/Objective-C编译器,致力于提供令人惊讶的快速编译,极其有用的错误和警告信息,提供一个可用于构建很棒的源代码级别的工具.</div><div class="line">dragonegg: gcc插件,可将GCC的优化和代码生成器替换为LLVM的相应工具。</div><div class="line">LLDB:基于LLVM提供的库和Clang构建的优秀的本地调试器。</div><div class="line">libc++、libc++ ABI: 符合标准的,高性能的C++标准库实现,以及对C++11的完整支持。</div><div class="line">compiler-rt:针对__fixunsdfdi和其他目标机器上没有一个核心IR(intermediate representation)对应的短原生指令序列时,提供高度调优过的底层代码生成支持。</div><div class="line">OpenMP: Clang中对多平台并行编程的runtime支持。</div><div class="line">vmkit:基于LLVM的Java和.NET虚拟机实</div><div class="line">polly: 支持高级别的循环和数据本地化优化支持的LLVM框架。</div><div class="line">libclc: OpenCL标准库的实现</div><div class="line">klee: 基于LLVM编译基础设施的符号化虚拟机</div><div class="line">SAFECode:内存安全的C/C++编译器</div><div class="line">lld: clang/llvm内置的链接器</div></pre></td></tr></table></figure></p>
<p><img src="/images/20170603/llvm_overView.png" alt=""><br><a href="http://llvm.org" target="_blank" rel="external">原文链接</a></p>
<p>1、clang源码并编译安装<br>查看<a href="https://luohs.github.io/2017/05/30/20170530/" target="_blank" rel="external">clang源码并编译安装</a><br>2、编写clang插件<br>要实现自定义的Clang插件(以C++为例),应按照以下步骤:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line">1.自定义继承自</div><div class="line"> clang::PluginASTAction(基于consumer的AST前端Action抽象基类)</div><div class="line"> clang::ASTConsumer(用于客户读取AST的抽象基类),</div><div class="line"> clang::RecursiveASTVisitor(前序或后续地深度优先搜索整个 AST,并访问每一个节点的基类)等基类,</div><div class="line">2.根据自身需要重载</div><div class="line"> PluginASTAction::CreateASTConsumer,</div><div class="line"> PluginASTAction::ParseArgs,</div><div class="line"> ASTConsumer::HandleTranslationUnit</div><div class="line"> RecursiveASTVisitor::VisitDecl</div><div class="line"> RecursiveASTVisitor::VisitStmt</div><div class="line"> 等方法,实现自定义的分析逻辑。</div><div class="line">3.注册插件</div><div class="line"> static FrontendPluginRegistry::Add<MyPlugin> X("my-plugin-name", "my-plugin-description");</div><div class="line">4.编译时载入插件</div><div class="line"> clang++ *** -Xclang -load -Xclang path-of-your-plugin.dylib -Xclang -add-plugin -Xclang your-pluginName -Xclang -plugin-arg-your-pluginName -Xclang your-pluginName-param</div></pre></td></tr></table></figure></p>
<p>编写clang插件:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div></pre></td><td class="code"><pre><div class="line">#include <iostream></div><div class="line">#include "clang/Frontend/FrontendPluginRegistry.h"</div><div class="line">#include "clang/AST/AST.h"</div><div class="line">#include "clang/AST/ASTConsumer.h"</div><div class="line">#include "clang/Frontend/CompilerInstance.h"</div><div class="line">#include "clang/AST/RecursiveASTVisitor.h"</div><div class="line">using namespace clang;</div><div class="line">using namespace std;</div><div class="line">using namespace llvm;</div><div class="line">namespace ClangPlugin</div><div class="line">{</div><div class="line"> class ClangPluginASTVisitor : public RecursiveASTVisitor<ClangPluginASTVisitor></div><div class="line"> {</div><div class="line"> private:</div><div class="line"> ASTContext *context;</div><div class="line"> public:</div><div class="line"> void setContext(ASTContext &context){</div><div class="line"> this->context = &context;</div><div class="line"> }</div><div class="line"> bool VisitDecl(Decl *decl){</div><div class="line"> if(isa<ObjCImplDecl>(decl)){</div><div class="line"> ObjCImplDecl *interDecl = (ObjCImplDecl*)decl;</div><div class="line"> cout<<"[KWLM]Class Implementation Found:"<<interDecl->getNameAsString()<<endl;</div><div class="line"> }</div><div class="line"> return true;</div><div class="line"> }</div><div class="line"> };</div><div class="line"></div><div class="line"> class ClangPluginASTConsumer : public ASTConsumer</div><div class="line"> {</div><div class="line"> private:</div><div class="line"> ClangPluginASTVisitor visitor;</div><div class="line"> void HandleTranslationUnit(ASTContext &context){</div><div class="line"> visitor.setContext(context);</div><div class="line"> visitor.TraverseDecl(context.getTranslationUnitDecl());</div><div class="line"> }</div><div class="line"> };</div><div class="line"></div><div class="line"> class ClangPluginASTAction : public PluginASTAction</div><div class="line"> {</div><div class="line"> public:</div><div class="line"> unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,StringRef InFile){</div><div class="line"> return unique_ptr<ClangPluginASTConsumer>(new ClangPluginASTConsumer);</div><div class="line"> }</div><div class="line"> bool ParseArgs(const CompilerInstance &CI, const std::vector<std::string>& args){</div><div class="line"> return true;</div><div class="line"> }</div><div class="line"> };</div><div class="line">}</div><div class="line">static clang::FrontendPluginRegistry::Add<ClangPlugin::ClangPluginASTAction>X("ClangPlugin", "ClangPlugin");</div></pre></td></tr></table></figure></p>
<p>编译生成插件(dylib):<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">clang -std=c++11 -stdlib=libc++ -L/opt/local/lib -L/opt/llvm/llvm_build/lib -I/opt/llvm/llvm_build/tools/clang/include -I/opt/llvm/llvm_build/include -I/opt/llvm/llvm/tools/clang/include -I/opt/llvm/llvm/include -dynamiclib -Wl,-headerpad_max_install_names -lclang -lclangFrontend -lclangAST -lclangAnalysis -lclangBasic -lclangCodeGen -lclangDriver -lclangFrontendTool -lclangLex -lclangParse -lclangSema -lclangEdit -lclangSerialization -lclangStaticAnalyzerCheckers -lclangStaticAnalyzerCore -lclangStaticAnalyzerFrontend -lLLVMX86CodeGen -lLLVMX86AsmParser -lLLVMX86Disassembler -lLLVMExecutionEngine -lLLVMAsmPrinter -lLLVMSelectionDAG -lLLVMX86AsmPrinter -lLLVMX86Info -lLLVMMCParser -lLLVMCodeGen -lLLVMX86Utils -lLLVMScalarOpts -lLLVMInstCombine -lLLVMTransformUtils -lLLVMAnalysis -lLLVMTarget -lLLVMCore -lLLVMMC -lLLVMSupport -lLLVMBitReader -lLLVMOption -lLLVMProfileData -lpthread -lcurses -lz -lstdc++ -fPIC -fno-common -Woverloaded-virtual -Wcast-qual -fno-strict-aliasing -pedantic -Wno-long-long -Wall -Wno-unused-parameter -Wwrite-strings -fno-rtti -fPIC your-clang-plugin-source.cpp -o your-clang-plugin-name.dylib</div></pre></td></tr></table></figure></p>
<p>使用clang编译oc文件(载入生成的your-clang-plugin-name.dylib):<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/opt/llvm/llvm_build/bin/clang -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator10.0.sdk -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1 -mios-version-min=8.0 -Xclang -load -Xclang ~/Desktop/your-clang-plugin-name.dylib -Xclang -add-plugin -Xclang your-clang-plugin-name -c ./ocClsDemo.m</div></pre></td></tr></table></figure></p>
<p>Xcode集成Clang插件:<br>要在Xcode中使用Clang插件,需要Hack Xcode.app。<br><a href="https://raw.githubusercontent.com/kangwang1988/kangwang1988.github.io/master/others/XcodeHacking.zip" target="_blank" rel="external">XcodeHacking.zip</a><br>通过command-line方式或者手动拷贝的方式将XcodeHack拷贝到Xcode目录中,如果Specifications文件不存在则手动创建一个。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">sudo mv HackedClang.xcplugin `xcode-select -print- path`/../PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library/Xcode/Plug-ins</div><div class="line">sudo mv HackedBuildSystem.xcspec `xcode-select -print- path`/../Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Specifications</div></pre></td></tr></table></figure></p>
<p><img src="/images/20170603/XcodeHack_plugin.png" alt=""><br><img src="/images/20170603/XcodeHack_spec.png" alt=""><br>之后在Xcode->Target-Build Settings->Build Options->Compiler for C/C++/Objective-C选择Clang LLVM Trunk即可使得Xcode使用1生成的的Clang来编译。至于其他的命令行参数,均可以通过Xcode设置完成。<br><img src="/images/20170603/XcodeHack_buildsetting.png" alt=""><br>3、clang插件在Xcode工程的配置:<br><a href="https://github.com/kangwang1988/XcodeZombieCode.git" target="_blank" rel="external">clang插件示例工程</a><br>a、首先通过Xcode将自定义clang插件编译成动态库(dylib)。<br><img src="/images/20170603/clang_plugin_out.png" alt=""><br><img src="/images/20170603/clang_plugin_out_2.png" alt=""><br>b、其次编译生成分析工具XcodeCodeAnalyser<br><img src="/images/20170603/clang_analyzer_out.png" alt=""><br><img src="/images/20170603/clang_analyzer_out_2.png" alt=""><br>c、设置工程<br>使用用户编译的Clang载入ClangPlugin去编译并生成各种中间文件。编译完成之后使用Xcode提供的post_build_action_shell机制调用分析工具,生成最终结果。<br><img src="/images/20170603/post_build_action_shell_1.png" alt=""><br><img src="/images/20170603/post_build_action_shell_2.png" alt=""><br><img src="/images/20170603/post_build_action_shell_script.png" alt=""></p>
<p>参考:<br><a href="http://railsware.com/blog/2014/02/28/creation-and-using-clang-plugin-with-xcode/" target="_blank" rel="external">http://railsware.com/blog/2014/02/28/creation-and-using-clang-plugin-with-xcode/</a><br><a href="http://blog.mrriddler.com/2017/02/24/Clang插件-Sherlock/" target="_blank" rel="external">http://blog.mrriddler.com/2017/02/24/Clang插件-Sherlock/</a><br><a href="https://lmsgsendnilself.github.io/blog/2017/02/28/clangtojszi-yuan/" target="_blank" rel="external">https://lmsgsendnilself.github.io/blog/2017/02/28/clangtojszi-yuan/</a><br><a href="http://kangwang1988.github.io/tech/2016/11/01/validate-ios-api-using-clang-plugin.html" target="_blank" rel="external">http://kangwang1988.github.io/tech/2016/11/01/validate-ios-api-using-clang-plugin.html</a><br><a href="https://github.com/kangwang1988/XcodeValidAPI" target="_blank" rel="external">https://github.com/kangwang1988/XcodeValidAPI</a><br><a href="http://www.cocoachina.com/ios/20151211/14562.html" target="_blank" rel="external">http://www.cocoachina.com/ios/20151211/14562.html</a><br><a href="http://mp.weixin.qq.com/s?__biz=MzA3ODg4MDk0Ng==&mid=2651112096&idx=1&sn=ce8fccce7d5f70e30c078e63e8ea0d15&scene=21#wechat_redirect" target="_blank" rel="external">http://mp.weixin.qq.com/s?__biz=MzA3ODg4MDk0Ng==&mid=2651112096&idx=1&sn=ce8fccce7d5f70e30c078e63e8ea0d15&scene=21#wechat_redirect</a></p>
</div>
<div>
</div>
<div>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
<link itemprop="mainEntityOfPage" href="http://yoursite.com/2017/06/01/20170602/">
<span style="display:none" itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="花生-sniper">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.jpg">
</span>
<span style="display:none" itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="三味猪屋">
<span style="display:none" itemprop="logo" itemscope itemtype="http://schema.org/ImageObject">
<img style="display:none;" itemprop="url image" alt="三味猪屋" src="">
</span>
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2017/06/01/20170602/" itemprop="url">
代码统计小贴示
</a>
</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="Post created" itemprop="dateCreated datePublished" datetime="2017-06-01T14:38:29+08:00">
2017-06-01
</time>
</span>
<span class="post-category" >
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/cloc/" itemprop="url" rel="index">
<span itemprop="name">cloc</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<script src="/assets/js/DPlayer.min.js"> </script><script src="/assets/js/APlayer.min.js"> </script><p><a href="https://osdn.net/frs/g_redir.php?m=netix&f=%2Fcloc%2Fcloc%2Fv1.64%2Fcloc-1.64.pl" target="_blank" rel="external">cloc-1.64.pl</a><br><a href="https://github.com/AlDanial/cloc" target="_blank" rel="external">CLOC源码地址</a><br>用法一:直接执行perl脚本,如图:<br><img src="/images/20170601A/cloc_script.png" alt=""><br>用法二:通过brew安装cloc,使用命令行方式,如图:<br><img src="/images/20170601A/cloc_commandline.png" alt=""></p>
</div>
<div>
</div>
<div>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
<link itemprop="mainEntityOfPage" href="http://yoursite.com/2017/06/01/20170601/">
<span style="display:none" itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="花生-sniper">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.jpg">
</span>
<span style="display:none" itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="三味猪屋">
<span style="display:none" itemprop="logo" itemscope itemtype="http://schema.org/ImageObject">
<img style="display:none;" itemprop="url image" alt="三味猪屋" src="">
</span>
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2017/06/01/20170601/" itemprop="url">
iOS包大小瘦身方案(一)- iOS安装包构成
</a>
</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="Post created" itemprop="dateCreated datePublished" datetime="2017-06-01T09:12:50+08:00">
2017-06-01
</time>
</span>
<span class="post-category" >
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/app-thinning/" itemprop="url" rel="index">
<span itemprop="name">app-thinning</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<script src="/assets/js/DPlayer.min.js"> </script><script src="/assets/js/APlayer.min.js"> </script><p>要想将iOS安装包瘦身,首先得熟悉iOS安装包的构成,然后根据各个部分逐个优化。<br>1、iOS安装包构成:<br>iOS安装包是以后缀名为“ipa”一个压缩包,该压缩包内容大致包含三块内容:可执行文件、资源文件、签名文件<br>构成如下图:<br><img src="/images/20170601/ipa_archive.png" alt=""><br>2、可执行文件构成:<br>可执行文件是通过编译器、连接器将我们编写的代码、静态库、动态库编译成的文件,大致可分为代码段和数据段<br>构成如下:<br><img src="/images/20170601/ipa_mach.png" alt=""><br>3、可执行文件支持的cpu架构以及安装包大小关系<br>以“滴滴打车”为例,对比去年3.9.7版本以及最新4.3.10版本<br>3.9.7版本:<br><img src="/images/20170601/didi_3_9_7.png" alt=""><br><img src="/images/20170601/didi_3_9_7_2.png" alt=""><br><img src="/images/20170601/didi_3_9_7_3.png" alt=""><br>4.3.10版本:<br><img src="/images/20170601/didi_4_3_10_1.png" alt=""><br><img src="/images/20170601/didi_4_3_10_2.png" alt=""><br><img src="/images/20170601/didi_4_3_10_3.png" alt=""><br>由此可见支持的CPU体系架构越多,对安装包大小成正比例影响。<br>4、可执行文件各段所占大小<br>64位架构:<br><img src="/images/20170601/ipa_archive_linkmap_arm64_1.png" alt=""><br><img src="/images/20170601/ipa_archive_linkmap_arm64_2.png" alt=""><br><img src="/images/20170601/ipa_archive_linkmap_arm64_3.png" alt=""><br>32位架构:<br><img src="/images/20170601/ipa_archive_linkmap_arm7_1.png" alt=""><br><img src="/images/20170601/ipa_archive_linkmap_arm7_2.png" alt=""><br><img src="/images/20170601/ipa_archive_linkmap_arm7_3.png" alt=""><br>5、第三方SDK大小占比<br><img src="/images/20170601/ipa_archive_sdk_linkmap_arm64.png" alt=""><br><img src="/images/20170601/ipa_archive_sdk_linkmap_arm7.png" alt=""><br><img src="/images/20170601/ipa_archive_sdk_size_1.png" alt=""><br><img src="/images/20170601/ipa_archive_sdk_size_2.png" alt=""><br><img src="/images/20170601/ipa_archive_size_1.png" alt=""><br><img src="/images/20170601/ipa_archive_size_2.png" alt=""><br>通过比较不难看出第三方SDK编译出来的可执行文件占比达到62.5%<br>6、资源文件对安装包的影响<br>未对图片资源进行无损压缩之后包大小<br><img src="/images/20170601/ipa_archive_size_4.png" alt=""><br>对图片资源进行无损压缩之后包大小<br><img src="/images/20170601/ipa_archive_size_3.png" alt=""><br>下图为对我们app中图片资源进行无损压缩的效果:<br><img src="/images/20170601/imageOptim.png" alt=""></p>
<p>Tips:<br>1、查看可执行文件大小:<br><img src="/images/20170601/linkmap_setting_1.png" alt=""><br><img src="/images/20170601/linkmap_setting_2.png" alt=""><br><img src="/images/20170601/linkmap_used.png" alt=""><br><a href="https://github.com/luohs/luohs.github.io/blob/master/images/20170601/linkmap.js" target="_blank" rel="external">linkmap.js</a><br>2、MachOView使用:<br><a href="http://sourceforge.net/projects/machoview/" target="_blank" rel="external">MachOView下载地址</a><br><a href="https://github.com/gdbinit/MachOView" target="_blank" rel="external">MachOView源码地址</a><br>3、ImageOptim使用:<br><a href="https://imageoptim.com/mac" target="_blank" rel="external">ImageOptim下载地址</a><br>4、去除工程中多余的图片资源:<br>a、脚本<br>详见<a href="https://stackoverflow.com/questions/6113243/how-to-find-unused-images-in-an-xcode-project/6113449#6113449" target="_blank" rel="external">链接</a><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">#!/bin/sh</div><div class="line">PROJ=`find . -name '*.xib' -o -name '*.[mh]'`</div><div class="line">for png in `find . -name '*.png'`</div><div class="line">do</div><div class="line">name=`basename $png`</div><div class="line">if ! grep -qhs "$name" "$PROJ"; then</div><div class="line"> echo "$png is not referenced"</div><div class="line">fi</div><div class="line">done</div></pre></td></tr></table></figure></p>
<p>b、Unused<br><a href="http://jeffhodnett.github.io/Unused/" target="_blank" rel="external">Unused</a><br>c、LSUnusedResources<br><a href="https://github.com/tinymind/LSUnusedResources/" target="_blank" rel="external">LSUnusedResources</a></p>
</div>
<div>
</div>
<div>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
<link itemprop="mainEntityOfPage" href="http://yoursite.com/2017/05/31/20170531/">
<span style="display:none" itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="花生-sniper">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.jpg">
</span>
<span style="display:none" itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="三味猪屋">
<span style="display:none" itemprop="logo" itemscope itemtype="http://schema.org/ImageObject">
<img style="display:none;" itemprop="url image" alt="三味猪屋" src="">
</span>
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2017/05/31/20170531/" itemprop="url">
深入理解"weak-strong dance"
</a>
</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="Post created" itemprop="dateCreated datePublished" datetime="2017-05-31T15:09:22+08:00">
2017-05-31
</time>
</span>
<span class="post-category" >
<span class="post-meta-divider">|</span>
<span class="post-meta-item-icon">
<i class="fa fa-folder-o"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/weak-strong-dance/" itemprop="url" rel="index">
<span itemprop="name">weak-strong dance</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<script src="/assets/js/DPlayer.min.js"> </script><script src="/assets/js/APlayer.min.js"> </script><p>使用block时利用”weak-strong dance”解决循环引用大家都知道,但这里有三点值得注意:<br>1、当self指向的对象已经被废弃的情况下,持有block成员变量也不存在了,这个时候block对象应该已经没有被变量所持有了,它的引用计数应该已经为0了,它应该被废弃了啊,为什么它还能继续存在并执行。<br>如以下代码,在 block 执行前退出这个页面的话,该 Controller 实例会被废弃,但 Block 还是会执行,会打印“self is (null)”。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line">- (void)viewDidLoad {</div><div class="line"> [super viewDidLoad];</div><div class="line"></div><div class="line"> __weak typeof(self) weakSelf = self;</div><div class="line"> self.handler = ^{</div><div class="line"> __strong typeof(weakSelf) strongSelf = weakSelf;</div><div class="line"> NSLog(@"self is %@", strongSelf);</div><div class="line"> };</div><div class="line"></div><div class="line"> NSTimeInterval interval = 6.0;</div><div class="line"> dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(interval * NSEC_PER_SEC)), dispatch_get_main_queue(), weakSelf.handler);</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>理解这个问题需要了解block原理,简单一点的说,block有三种类型:<br>NSConcreteStackBlock(栈)<br>NSConcreteGlobalBlock(全局)<br>NSConcreteMallocBlock(堆)</p>
<p>如何实现这三种类型的block:<br><img src="/images/20170531/block_objc.png" alt=""><br>使用<code>clang -rewrite-objc $filePath</code>将OC代码转化为C++代码实现。<a href="https://luohs.github.io/2017/05/30/20170530/" target="_blank" rel="external">如何安装编译clang</a><br><img src="/images/20170531/clang_rewrite.png" alt=""><br><img src="/images/20170531/block_clang.png" alt=""><br>如果 block 在记述全局变量的地方被设置或者 block 没有捕获外部变量,那就生成一个 NSConcreteGlobalBlock 实例。其它情况都会生成一个 NSConcreteStackBlock 实例,也就是说,它是在栈上的,所以一旦它所属的变量超出了变量作用域,该 block 就被废弃了。而当发生以下任一情况时:<br>a、手动调用 block 的实例方法copy。<br>b、block 作为函数返回值返回。<br>c、将 block 赋值给附有__strong修饰符的成员变量。<br>d、在方法名中含有usingBlock的 Cocoa 框架方法或 GCD 的 API 中传递 block。<br>所以NSConcreteMallocBlock 类型的 block 通常不会在源码中直接出现。<br><a href="http://www.galloway.me.uk/2013/05/a-look-inside-blocks-episode-3-block-copy/" target="_blank" rel="external">看一下Block_copy()实现</a>:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div></pre></td><td class="code"><pre><div class="line">static void *_Block_copy_internal(const void *arg, const int flags) {</div><div class="line"> struct Block_layout *aBlock;</div><div class="line"> const bool wantsOne = (WANTS_ONE & flags) == WANTS_ONE;</div><div class="line"></div><div class="line"> // 1</div><div class="line"> if (!arg) return NULL;</div><div class="line"></div><div class="line"> // 2</div><div class="line"> aBlock = (struct Block_layout *)arg;</div><div class="line"></div><div class="line"> // 3</div><div class="line"> if (aBlock->flags & BLOCK_NEEDS_FREE) {</div><div class="line"> // latches on high</div><div class="line"> latching_incr_int(&aBlock->flags);</div><div class="line"> return aBlock;</div><div class="line"> }</div><div class="line"></div><div class="line"> // 4</div><div class="line"> else if (aBlock->flags & BLOCK_IS_GLOBAL) {</div><div class="line"> return aBlock;</div><div class="line"> }</div><div class="line"></div><div class="line"> // 5</div><div class="line"> struct Block_layout *result = malloc(aBlock->descriptor->size);</div><div class="line"> if (!result) return (void *)0;</div><div class="line"></div><div class="line"> // 6</div><div class="line"> memmove(result, aBlock, aBlock->descriptor->size); // bitcopy first</div><div class="line"></div><div class="line"> // 7</div><div class="line"> result->flags &= ~(BLOCK_REFCOUNT_MASK); // XXX not needed</div><div class="line"> result->flags |= BLOCK_NEEDS_FREE | 1;</div><div class="line"></div><div class="line"> // 8</div><div class="line"> result->isa = _NSConcreteMallocBlock;</div><div class="line"></div><div class="line"> // 9</div><div class="line"> if (result->flags & BLOCK_HAS_COPY_DISPOSE) {</div><div class="line"> (*aBlock->descriptor->copy)(result, aBlock); // do fixup</div><div class="line"> }</div><div class="line"></div><div class="line"> return result;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>综上所述,已经可以解答问题1。把 block 赋值给self.handler的时候,在栈上生成的 block 被复制了一份放到堆上。而之后如果你把这个 block 当作 GCD 参数使用,GCD 函数内部会把该 block 再 copy 一遍,而此时 block 已经在堆上,则该 block 的引用计数加1。所以此时 block 的引用计数是大于1的,即使self对象被废弃 block 会被 release 一次,但它的引用计数仍然大于0,故而不会被废弃。<br>Tips:<br>其实在 ARC 开启的情况下,将只会有 NSConcreteGlobalBlock 和 NSConcreteMallocBlock 类型的 block。<br><img src="/images/20170531/block_work_in_ARC.png" alt=""><br>更多请查看<a href="https://developer.apple.com/library/content/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html" target="_blank" rel="external">苹果官方文档</a></p>
<p>2、在 block 内部使用weakSelf就是为了让 block 对象不持有self指向的对象,那在 block 内部又把weakSelf赋给strongSelf不就又持有self对象了么?又循环引用了?<br>理解这个问题就需要了解block捕获对象变量。<br>使用<strong>weak修饰的变量时</strong>weak是不会持有对象,它用一张 weak 表来管理对象和变量。赋值的时候它会以赋值对象的地址作为 key,变量的地址为 value,注册到 weak 表中。一旦该对象被废弃,就通过对象地址在 weak 表中找到变量的地址,赋值为 nil,然后将该条记录从 weak 表中删除。<br>那使用 “weak-strong dance” 的时候是怎么个情况呢?<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line">struct __block_impl {</div><div class="line"> void *isa;</div><div class="line"> int Flags;</div><div class="line"> int Reserved;</div><div class="line"> void *FuncPtr;</div><div class="line">};</div><div class="line"></div><div class="line">struct __xx_block_impl_y {</div><div class="line"> struct __block_impl impl;</div><div class="line"> __weak OCClass *occlass;</div><div class="line"> // ...</div><div class="line">};</div><div class="line"></div><div class="line">static void __xx_block_func_y(struct __xx_block_impl_y *__cself) {</div><div class="line"> OCClass *occlass = __cself -> occlass;</div><div class="line"> // ...</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>每次使用<strong>weak变量的时候,都会取出该变量指向的对象并 retain,然后将该对象注册到 autoreleasepool 中。通过上述代码我们可以发现,在</strong>xx_block_func_y中,局部变量occlass会持有捕获的对象,然后对象会被注册到 autoreleasepool。这是延长对象生命周期的关键(保证在执行 Block 期间对象不会被废弃),但这不会造成循环引用,当函数执行结束,变量occlass超出作用域,过一会儿(一般一次 RunLoop 之后),对象就被释放了。所以 weak-strong dance 的行为非常符合预期:延长捕获对象的生命周期,一旦 Block 执行完,对象被释放,而 Block 也会被释放(如果被 GCD 之类的 API copy 过一次增加了引用计数,那最终也会被 GCD 释放)。</p>
<p>3、使用”weak-strong dance”一定安全吗?<br>其实通过问题2就可以理解,”weak-strong dance”并不是安全的,”weak-strong dance”只实用与block已经捕获到对象的情况,”weak-strong dance”并不能保证 block 所引用对象的释放时机在执行之后, 更安全的做法应该是在 block 内部使用 strongSelf 时进行 nil检测,这样可以避免上述情况。</p>
<p>参考:<br><a href="https://developer.apple.com/library/content/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html" target="_blank" rel="external">https://developer.apple.com/library/content/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html</a><br><a href="http://www.galloway.me.uk/2013/05/a-look-inside-blocks-episode-3-block-copy/" target="_blank" rel="external">http://www.galloway.me.uk/2013/05/a-look-inside-blocks-episode-3-block-copy/</a><br><a href="http://blog.devtang.com/2013/07/28/a-look-inside-blocks/" target="_blank" rel="external">http://blog.devtang.com/2013/07/28/a-look-inside-blocks/</a><br><a href="http://albertodebortoli.com/blog/2013/08/03/objective-c-blocks-caveat/" target="_blank" rel="external">http://albertodebortoli.com/blog/2013/08/03/objective-c-blocks-caveat/</a><br><a href="http://www.jianshu.com/p/737999a30544" target="_blank" rel="external">http://www.jianshu.com/p/737999a30544</a></p>
</div>
<div>
</div>
<div>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
<link itemprop="mainEntityOfPage" href="http://yoursite.com/2017/05/30/20170530/">
<span style="display:none" itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="花生-sniper">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.jpg">
</span>
<span style="display:none" itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="三味猪屋">
<span style="display:none" itemprop="logo" itemscope itemtype="http://schema.org/ImageObject">
<img style="display:none;" itemprop="url image" alt="三味猪屋" src="">
</span>
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2017/05/30/20170530/" itemprop="url">
clang源码编译安装
</a>
</h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="Post created" itemprop="dateCreated datePublished" datetime="2017-05-30T21:40:11+08:00">
2017-05-30
</time>