-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
1376 lines (1119 loc) · 65.1 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 lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.0.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16.png">
<link rel="mask-icon" href="/images/safari-pinned-tab.svg" color="#222">
<meta name="msapplication-config" content="/images/browserconfig.xml">
<link rel="alternate" href="/atom.xml" title="记录过程" type="application/atom+xml">
<link rel="stylesheet" href="/css/main.css">
<link rel="stylesheet" href="/lib/font-awesome/css/font-awesome.min.css">
<script id="hexo-configurations">
var NexT = window.NexT || {};
var CONFIG = {
root: '/',
scheme: 'Pisces',
version: '7.5.0',
exturl: false,
sidebar: {"position":"left","display":"post","offset":12,"onmobile":false},
copycode: {"enable":false,"show_result":false,"style":"default"},
back2top: {"enable":true,"sidebar":false,"scrollpercent":true},
bookmark: {"enable":false,"color":"#222","save":"auto"},
fancybox: false,
mediumzoom: false,
lazyload: false,
pangu: true,
algolia: {
appID: '',
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"}
},
localsearch: {"enable":false,"trigger":"auto","top_n_per_article":5,"unescape":false,"preload":false},
path: '',
motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
translation: {
copy_button: '复制',
copy_success: '复制成功',
copy_failure: '复制失败'
},
sidebarPadding: 40
};
</script>
<meta name="description" content="一名移动端开发者,但不限于移动端端技术(学无止境...)">
<meta name="keywords" content="oc, java, flutter, swift, js, python">
<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 property="og:description" content="一名移动端开发者,但不限于移动端端技术(学无止境...)">
<meta property="og:locale" content="zh-CN">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="http://yoursite.com/">
<script id="page-configurations">
// https://hexo.io/docs/variables.html
CONFIG.page = {
sidebar: "",
isHome: true,
isPost: false,
isPage: false,
isArchive: false
};
</script>
<title>记录过程</title>
<noscript>
<style>
.use-motion .brand,
.use-motion .menu-item,
.sidebar-inner,
.use-motion .post-block,
.use-motion .pagination,
.use-motion .comments,
.use-motion .post-header,
.use-motion .post-body,
.use-motion .collection-header { opacity: initial; }
.use-motion .site-title,
.use-motion .site-subtitle {
opacity: initial;
top: initial;
}
.use-motion .logo-line-before i { left: initial; }
.use-motion .logo-line-after i { right: initial; }
</style>
</noscript>
</head>
<body itemscope itemtype="http://schema.org/WebPage">
<div class="container use-motion">
<div class="headband"></div>
<header class="header" itemscope itemtype="http://schema.org/WPHeader">
<div class="header-inner"><div class="site-brand-container">
<div class="site-meta">
<div>
<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">
<div class="toggle" aria-label="切换导航栏">
<span class="toggle-line toggle-line-first"></span>
<span class="toggle-line toggle-line-middle"></span>
<span class="toggle-line toggle-line-last"></span>
</div>
</div>
</div>
<nav class="site-nav">
<ul id="menu" class="menu">
<li class="menu-item menu-item-home">
<a href="/" rel="section"><i class="fa fa-fw fa-home"></i>首页</a>
</li>
<li class="menu-item menu-item-tags">
<a href="/tags/" rel="section"><i class="fa fa-fw fa-tags"></i>标签</a>
</li>
<li class="menu-item menu-item-categories">
<a href="/categories/" rel="section"><i class="fa fa-fw fa-th"></i>分类</a>
</li>
<li class="menu-item menu-item-archives">
<a href="/archives/" rel="section"><i class="fa fa-fw fa-archive"></i>归档</a>
</li>
</ul>
</nav>
</div>
</header>
<div class="back-to-top">
<i class="fa fa-arrow-up"></i>
<span>0%</span>
</div>
<div class="reading-progress-bar"></div>
<main class="main">
<div class="main-inner">
<div class="content-wrap">
<div class="content">
<div class="posts-expand">
<article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/12/23/iOS-crash/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar_myself.jpeg">
<meta itemprop="name" content="coyeli">
<meta itemprop="description" content="一名移动端开发者,但不限于移动端端技术(学无止境...)">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="记录过程">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a href="/2019/12/23/iOS-crash/" class="post-title-link" itemprop="url">iOS Crash 总结</a>
</h1>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2019-12-23 10:54:33" itemprop="dateCreated datePublished" datetime="2019-12-23T10:54:33+08:00">2019-12-23</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-check-o"></i>
</span>
<span class="post-meta-item-text">更新于</span>
<time title="修改时间:2019-12-24 15:11:41" itemprop="dateModified" datetime="2019-12-24T15:11:41+08:00">2019-12-24</time>
</span>
<span class="post-meta-item">
<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/iOS/" itemprop="url" rel="index">
<span itemprop="name">iOS</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h3 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h3><ul>
<li>符号化:就是把内存地址用可读的函数名与行数来替换</li>
</ul>
<h4 id="符号化-crash-report"><a href="#符号化-crash-report" class="headerlink" title="符号化 crash report"></a>符号化 crash report</h4><pre><code>符号化是指把堆栈信息(二进制信息)解释成源码里的方法名或者函数名,也就是所谓符号
</code></pre><ul>
<li><p>编译器源代码 -> 机器码,会生成一份对应的 debug 符号表(映射表)</p>
</li>
<li><p>映射表把编译好的二进制信息中隐藏的机器指令映射到每一行源码中</p>
</li>
<li><p>符号表可储存在 binary信息中,也可储存在 debug symbol文件(DSYM文件)</p>
</li>
<li><p>build setting -> debug information format 可以设置是否生成dsym debug符号表</p>
</li>
<li><p>debug 下 符号表一般储存在二进制信息中,release 下储存在单独的 dsym 文件中,以节省包体积</p>
</li>
<li><p>同一次构建, app + DSYM + UUID配套存在,三者的 uuid 不同,无法进行符号化</p>
</li>
</ul>
<h4 id="bitcode"><a href="#bitcode" class="headerlink" title="bitcode"></a>bitcode</h4><ul>
<li><p>bitcode 开启后,编译器生成的二进制中包含的是 bitcode 中间码,而不是机器码,上传 appstore 后才会被编译成机器码</p>
</li>
<li><p>开启 bitcode 后的 DSYM 获取在 ITC网站上</p>
</li>
<li><p>开启 bitcode 后,假如上传 app 到 appstore 没有勾选 “上传你的app的符号表信息以便从 apple 那边接收符号化过的 report” 选项, xcode会用一种符号替换app的 dsym文件,然后将其储存在 app 文件的 bcsymbolmap文件</p>
</li>
<li><p>符号化之前, xcode中的下载 dsym,解析会自动完成,否则要使用如下命令<br><code>xcrun dsymutil -symbol-map ~/Library/Developer/Xcode/Archives/xxx/xxx/xx.xcarchive/BCSymbolMaps ~/Downloads/dSYMs/xxx.dSYM</code></p>
</li>
</ul>
<h4 id="xcode-符号化-crash-report-条件"><a href="#xcode-符号化-crash-report-条件" class="headerlink" title="xcode 符号化 crash report 条件"></a>xcode 符号化 crash report 条件</h4><ul>
<li><p>闪退 app 的二进制信息以及 DSYM 文件</p>
</li>
<li><p>app 关联的自定义 framework 的二进制信息以及 DSYM文件</p>
</li>
<li><p>发生 crash 的时候 app 所依赖的<strong>系统</strong>的符号表信息(发生crash时候的手机等系统版本)</p>
</li>
</ul>
<h4 id="auto-符号化-crash-report"><a href="#auto-符号化-crash-report" class="headerlink" title="auto 符号化 crash report"></a>auto 符号化 crash report</h4><pre><code>auto 命令可以把地址里的数字替换成等价的符号,输出包含文件名和对应的资源行数。 auto 也可以单独符号化 crash report。
</code></pre><ul>
<li><p>对应 DSYM文件</p>
</li>
<li><p>二进制名称</p>
</li>
<li><p>二进制 加载地址</p>
</li>
<li><p>要解析的内存地址</p>
</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">atos -arch <Binary Architecture> -o <Path to dSYM file>/Contents/Resources/DWARF/<binary image name> -l <load address> <address to symbolicate></span><br><span class="line"></span><br><span class="line">$ atos -arch arm64 -o xxxx.app.dSYM/Contents/Resources/DWARF/xxxx -l 0xxxxxxxxxxx 0xxxxxxxxxxxxx</span><br></pre></td></tr></table></figure>
<h4 id="分析crash-report"><a href="#分析crash-report" class="headerlink" title="分析crash report"></a>分析crash report</h4><h5 id="header"><a href="#header" class="headerlink" title="header"></a>header</h5><p><img src="../images/crash_header.png" alt="crash header" title="header"></p>
<ul>
<li><p>Incident Identifier:一个crash report的唯一ID。两个 report不会使用同一个Incident Identifier</p>
</li>
<li><p>CrashReporter Key:一个匿名的设备相关ID,同一个设备的两篇crash report会有相同的CrashReporter Key</p>
</li>
<li><p>Process:发生Crash时的进程名。这个和app信息属性列表里的CFBundleExecutable Key中的值可以匹配上</p>
</li>
<li><p>Code Type:crash 架构 arm64 arm7等</p>
</li>
<li><p>Role:在发生crash时进程的的task_role</p>
</li>
</ul>
<h4 id="异常信息"><a href="#异常信息" class="headerlink" title="异常信息"></a>异常信息</h4><pre><code>列举 Mach 异常类型和相应的能提供对解crash有关的一些信息
</code></pre><p><img src="../images/crash_exception.png" alt="crash type" title="type"></p>
<ul>
<li><p>Exception Codes:和异常是有关的处理器指定信息,这些信息会被编码成一个或者多个64位二进制数字</p>
</li>
<li><p>Exception Subtype:可读的exception code的名称</p>
</li>
<li><p>Exception Message:从exception code中解析出来的附加的可读信息</p>
</li>
<li><p>Exception Note:不特指某一种异常的额外信息。如果这个字段包含”SIMULATED”(不是Crash),则进程并没有发生crash,而是在系统层面被kill掉了,比如看门狗机制,机制触发如下:</p>
</li>
</ul>
<div class="table-container">
<table>
<thead>
<tr>
<th>触发时机</th>
<th>看门狗出动实践</th>
</tr>
</thead>
<tbody>
<tr>
<td>启动</td>
<td>20s</td>
</tr>
<tr>
<td>恢复运行</td>
<td>10s</td>
</tr>
<tr>
<td>悬挂进程</td>
<td>10s</td>
</tr>
<tr>
<td>退出应用</td>
<td>6s</td>
</tr>
<tr>
<td>后台运行</td>
<td>10min</td>
</tr>
</tbody>
</table>
</div>
<ul>
<li>Termination Reason:当进程被终止时的原因及信息</li>
<li>Triggered by Thread: 异常发生的线程</li>
</ul>
<h4 id="常见异常类型"><a href="#常见异常类型" class="headerlink" title="常见异常类型"></a>常见异常类型</h4><ul>
<li><p>Bad Memory Access [EXC_BAD_ACCESS // SIGSEGV // SIGBUS]</p>
<ul>
<li><p>进程试图去访问无效的内存空间,或者尝试访问的方法是不被允许的(例如给只读的内存空间做写操作)。在Exception Subtype字段中如果出现kern_return_t的话,说明内存地址空间被不正确的访问了。</p>
</li>
<li><p>如果 objc_msgSend 或者 objc_release出现在crash的线程的附近,则进程有可能尝试去给一个被释放的对象发送消息</p>
</li>
<li><p>如果gpus_ReturnNotPermittedKillClient在近crash的线程附近,则进程有可能是尝试在后台通过OpenGL ES或者Metal来做渲染。</p>
</li>
</ul>
</li>
</ul>
<ul>
<li><p>Abnormal Exit [EXC_CRASH // SIGABRT]</p>
<ul>
<li>进程异常退出。这种异常最常见的原因在于uncaught Objective-C/C++ exception并且调用了abort()。</li>
</ul>
</li>
<li><p>Trace Trap [EXC_BREAKPOINT // SIGTRAP]</p>
<ul>
<li>由于在特殊的节点加入debugger调试节点的原因</li>
</ul>
</li>
<li><p>Illegal Instruction [EXC_BAD_INSTRUCTION // SIGILL]</p>
<ul>
<li>当尝试去执行一个非法或者未定义的指令时会触发该异常。有可能是因为线程在一个配置错误的函数指针的误导下尝试jump到一个无效地址</li>
</ul>
</li>
<li><p>Quit [SIGQUIT]</p>
<ul>
<li>这个异常是由于其它进程拥有高优先级且可以管理本进程(因此被高优先级进程Kill掉)所导致。SIGQUIT不代表进程发生Crash了,但是它确实反映了某种不合理的行为 </li>
</ul>
</li>
<li><p>Killed[SIGKILL]</p>
<ul>
<li>进程收到系统指令被干掉</li>
</ul>
</li>
<li><p>Guarded Resource Violation [EXC_GUARD]</p>
<ul>
<li>进程违规访问了一个被保护的资源</li>
</ul>
</li>
<li><p>Resource Limit [EXC_RESOURCE]</p>
<ul>
<li>进程的资源超过限定阈值。这条推送是OS发出的,表示进程占有了太多的资源。准确的资源列在了Exception Subtype的字段里。如果Exception Note字段包含了NON-FATAL CONDITION(非严重错误),则即便是生成了crash report,进程也不会被kill掉。</li>
<li>如果EXCEPTION SUBTYPE里出现MEMORY则暗示了进程占用已经超过系统限制。如果之后出现由于系统占用过多进程被Kill,可能和这有关</li>
<li>如果EXCEPTION SUBTYPE里出现WAKEUP则暗示线程每秒被进程唤醒太多次了,进而导致CPU被频繁唤醒并且造成电量损耗</li>
</ul>
</li>
<li><p>Other Exception Types:看 Exception Code</p>
<ul>
<li>0xbaaaaaad:则说明此条logs是系统堆栈快照,并非crash report</li>
<li>0xbad22222:表示一个VoIP应用因为频繁暂停被iOS系统终止掉</li>
<li>0xc00010ff:则说明app因为环境过热(的事件)被iOS系统干掉了</li>
<li>0xdead10cc:(读起来像deadlock)则说明一个应用被系统终止掉,原因是在应用挂起时拿到了文件锁或者sqlite数据库所长期不释放直到被冻结</li>
<li>0x2bad45ec:说明app因为违规操作(安全违规)被iOS系统终止</li>
</ul>
</li>
</ul>
<h4 id="堆栈信息"><a href="#堆栈信息" class="headerlink" title="堆栈信息"></a>堆栈信息</h4><pre><code>最重要的一部分信息
</code></pre><p><img src="../images/crash_body.png" alt="crash body" title="body"></p>
<ul>
<li><p>给之前已经释放的对象发送消息会引发NSInvalidArgumentException异常进而crash,而非内存访问违规</p>
</li>
<li><p>如果异常没有被捕捉到,他会被一个叫uncaught exception方法所拦截,这种叫异常堆栈</p>
</li>
<li><p>如果你发现本应该被捕捉的异常并没有被捕捉到,请确定您没有在building应用或者library时添加了-no_compact_unwind标签</p>
</li>
</ul>
<h4 id="Binary-Images"><a href="#Binary-Images" class="headerlink" title="Binary Images"></a>Binary Images</h4><pre><code>其中包含以下重要信息
</code></pre><p><img src="../images/crash_images.png" alt="crash images" title="images"></p>
<ul>
<li><p>在进程内的二进制文件的地址空间</p>
</li>
<li><p>二进制文件的架构名</p>
</li>
<li><p>一个可以唯一标示二进制文件的id,即UUID</p>
</li>
<li><p>磁盘上二进制文件的path</p>
</li>
</ul>
<h3 id="实践"><a href="#实践" class="headerlink" title="实践"></a>实践</h3><p> 补充准备中…</p>
<h3 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h3><ul>
<li><a href="https://wetest.qq.com/lab/view/404.html?" target="_blank" rel="noopener">了解和分析iOS Crash</a></li>
<li><a href="https://www.codenong.com/js55c4d666adf7/" target="_blank" rel="noopener">iOS Crash日志字段解析</a></li>
</ul>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/12/19/thread-safe/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar_myself.jpeg">
<meta itemprop="name" content="coyeli">
<meta itemprop="description" content="一名移动端开发者,但不限于移动端端技术(学无止境...)">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="记录过程">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a href="/2019/12/19/thread-safe/" class="post-title-link" itemprop="url">thread-safe</a>
</h1>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2019-12-19 16:36:07 / 修改时间:16:50:15" itemprop="dateCreated datePublished" datetime="2019-12-19T16:36:07+08:00">2019-12-19</time>
</span>
<span class="post-meta-item">
<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/iOS/" itemprop="url" rel="index">
<span itemprop="name">iOS</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h3 id="线程安全一个小case"><a href="#线程安全一个小case" class="headerlink" title="线程安全一个小case"></a>线程安全一个小case</h3><blockquote>
<p>代码示例</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line">- (void)moreThreadSafe {</span><br><span class="line"> pthread_mutex_init(&_mutex, NULL);</span><br><span class="line"> self.threadStr = @"thread safe after";</span><br><span class="line"> [self performSelector:@selector(doSomething) withObject:nil afterDelay:0.5];</span><br><span class="line"></span><br><span class="line"> /*</span><br><span class="line"> * 示例代码一</span><br><span class="line"> dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{</span><br><span class="line"> NSLog(@"before sleep %@",self.threadStr);</span><br><span class="line"> sleep(3);</span><br><span class="line"> NSLog(@"after sleep %@",self.threadStr);</span><br><span class="line"> });*/</span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"> // 示例代码二</span><br><span class="line"> __weak typeof(self.threadStr)weakString = self.threadStr;</span><br><span class="line"> dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{</span><br><span class="line"> __strong __typeof(weakString) strongString = weakString;</span><br><span class="line"> NSLog(@"before sleep %@",strongString);</span><br><span class="line"> sleep(3);</span><br><span class="line"> NSLog(@"after sleep %@",strongString);</span><br><span class="line"> });</span><br><span class="line"> </span><br><span class="line"> /*</span><br><span class="line"> * 示例代码三</span><br><span class="line"> dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{</span><br><span class="line"> pthread_mutex_lock(&self->_mutex);</span><br><span class="line"> NSLog(@"before sleep %@",self.threadStr);</span><br><span class="line"> sleep(3);</span><br><span class="line"> NSLog(@"after sleep %@",self.threadStr);</span><br><span class="line"> pthread_mutex_unlock(&self->_mutex);</span><br><span class="line"> });*/</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">- (void)doSomething {</span><br><span class="line"> pthread_mutex_lock(&_mutex);</span><br><span class="line"> self.threadStr = @"thread safe changed";</span><br><span class="line"> pthread_mutex_unlock(&_mutex);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<blockquote>
<p>说明</p>
</blockquote>
<p>为了保证异步子线程对资源(例如示例代码中的 self.threadStr )的独占,防止资源竞争,需要保证子线程的不被改变,因此类似示例一代码的写法,就不能保证这个问题,示例二代码通过改变数据储存指针的方式保证了不被更改,同时也保证了野指针的问题,示例三通过加锁的方式也保证了这种问题的出现,但加入此资源使用地方较多,不建议这种方式。</p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/11/06/git-use/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar_myself.jpeg">
<meta itemprop="name" content="coyeli">
<meta itemprop="description" content="一名移动端开发者,但不限于移动端端技术(学无止境...)">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="记录过程">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a href="/2019/11/06/git-use/" class="post-title-link" itemprop="url">Git常用命令</a>
</h1>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2019-11-06 15:10:15 / 修改时间:17:25:31" itemprop="dateCreated datePublished" datetime="2019-11-06T15:10:15+08:00">2019-11-06</time>
</span>
<span class="post-meta-item">
<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/Tool/" itemprop="url" rel="index">
<span itemprop="name">Tool</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h3 id="命令列表"><a href="#命令列表" class="headerlink" title="命令列表"></a>命令列表</h3><blockquote>
<p>初始化</p>
</blockquote>
<ul>
<li><p>在当前目录新建一个Git代码库</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git init</span><br></pre></td></tr></table></figure>
</li>
<li><p>下载一个项目和它的整个代码历史 [Git only]</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> [url]</span><br></pre></td></tr></table></figure>
</li>
</ul>
<blockquote>
<p>配置</p>
</blockquote>
<ul>
<li><p>列举所有配置</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git config -l</span><br></pre></td></tr></table></figure></li>
<li><p>为命令配置别名</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">git config --global alias.co checkout</span><br><span class="line">git config --global alias.ci commit</span><br><span class="line">git config --global alias.st status</span><br><span class="line">git config --global alias.br branch</span><br></pre></td></tr></table></figure></li>
</ul>
<ul>
<li><p>设置提交代码时的用户信息</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git config [--global] user.name <span class="string">"[name]"</span></span><br><span class="line">git config [--global] user.email <span class="string">"[email address]"</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
<blockquote>
<p>增删文件</p>
</blockquote>
<ul>
<li><p>添加当前目录的所有文件到暂存区</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git add .</span><br></pre></td></tr></table></figure></li>
<li><p>添加指定文件到暂存区</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git add ...</span><br></pre></td></tr></table></figure></li>
<li><p>添加指定目录到暂存区,包括其子目录</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git add</span><br></pre></td></tr></table></figure></li>
<li><p>删除工作区文件,并且将这次删除放入暂存区</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git rm [file1] [file2] ...</span><br></pre></td></tr></table></figure></li>
<li><p>停止追踪指定文件,但该文件会保留在工作区</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git rm --cached [file]</span><br></pre></td></tr></table></figure></li>
<li><p>改名文件,并且将这个改名放入暂存区</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git mv [file-original][file-renamed]</span><br></pre></td></tr></table></figure>
</li>
</ul>
<blockquote>
<p>分支</p>
</blockquote>
<ul>
<li><p>列出所有本地分支</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git branch</span><br></pre></td></tr></table></figure>
</li>
<li><p>列出所有本地分支和远程分支</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git branch -a</span><br></pre></td></tr></table></figure>
</li>
<li><p>新建一个分支,但依然停留在当前分支</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git branch [branch-name]</span><br></pre></td></tr></table></figure>
</li>
<li><p>新建一个分支,并切换到该分支</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git checkout -b [new_branch] [remote-branch]</span><br></pre></td></tr></table></figure>
</li>
<li><p>切换到指定分支,并更新工作区</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git checkout [branch-name]</span><br></pre></td></tr></table></figure>
</li>
<li><p>合并指定分支到当前分支</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git merge [branch]</span><br></pre></td></tr></table></figure>
</li>
<li><p>选择一个 commit,合并进当前分支</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git cherry-pick [commit]</span><br></pre></td></tr></table></figure>
</li>
<li><p>删除本地分支,-D 参数强制删除分支</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git branch -d [branch-name]</span><br></pre></td></tr></table></figure>
</li>
<li><p>删除远程分支</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git push [remote] :[remote-branch]</span><br></pre></td></tr></table></figure>
</li>
<li><p>在本地创建和远程分支对应的分支</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git checkout -b branch-name origin/branch-name</span><br></pre></td></tr></table></figure>
</li>
<li><p>建立本地分支和远程分支的关联</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git branch --set-upstream-to=origin/</span><br></pre></td></tr></table></figure>
</li>
</ul>
<blockquote>
<p>提交</p>
</blockquote>
<ul>
<li><p>提交暂存区到仓库区</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git commit -m [message]</span><br></pre></td></tr></table></figure>
</li>
<li><p>提交工作区与暂存区的变化直接到仓库区</p>
<pre><code> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git commit -a</span><br></pre></td></tr></table></figure>
</code></pre></li>
<li><p>提交时显示所有 diff 信息</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git commit -v</span><br></pre></td></tr></table></figure>
</li>
<li><p>提交暂存区修改到仓库区,合并到上次修改,并修改上次的提交信息</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git commit --amend -m [message]</span><br></pre></td></tr></table></figure>
</li>
<li><p>上传本地指定分支到远程仓库</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git push [remote] [remote-branch]</span><br></pre></td></tr></table></figure>
</li>
</ul>
<blockquote>
<p>拉取</p>
</blockquote>
<ul>
<li><p>下载远程仓库的所有变动 (Git only)</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git fetch [remote]</span><br></pre></td></tr></table></figure>
</li>
<li><p>显示所有远程仓库 (Git only)</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git remote -v</span><br></pre></td></tr></table></figure>
</li>
<li><p>显示某个远程仓库的信息 (Git only)</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git remote show [remote]</span><br></pre></td></tr></table></figure>
</li>
<li><p>增加一个新的远程仓库,并命名 (Git only)</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git remote add [remote-name] [url]</span><br></pre></td></tr></table></figure>
</li>
<li><p>取回远程仓库的变化,并与本地分支合并,(Git only), 若使用 Git-SVN,请查看第三节</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git pull [remote] [branch]</span><br></pre></td></tr></table></figure>
</li>
<li><p>取回远程仓库的变化,并与本地分支变基合并,(Git only), 若使用 Git-SVN,请查看第三节</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git pull --rebase [remote] [branch]</span><br></pre></td></tr></table></figure>
</li>
<li><p>拉取远程代码后执行rebase,整理提交线</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git rebase</span><br></pre></td></tr></table></figure>
</li>
<li><p>拉取后如果有冲突,先本地解决冲突后,重新</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git add -> git commit -> git rebase —continu</span><br></pre></td></tr></table></figure>
</li>
</ul>
<blockquote>
<p>撤销</p>
</blockquote>
<ul>
<li><p>恢复暂存区的指定文件到工作区</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git checkout [file]</span><br></pre></td></tr></table></figure>
</li>
<li><p>恢复暂存区当前目录的所有文件到工作区</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git checkout .</span><br></pre></td></tr></table></figure>
</li>
<li><p>恢复工作区到指定 commit</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git checkout [commit]</span><br></pre></td></tr></table></figure>
</li>
<li><p>重置暂存区的指定文件,与上一次 commit 保持一致,但工作区不变</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git reset [file]</span><br></pre></td></tr></table></figure></li>
<li><p>重置暂存区与工作区,与上一次 commit 保持一致</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git reset --hard</span><br></pre></td></tr></table></figure>
</li>
<li><p>重置当前分支的指针为指定 commit,同时重置暂存区,但工作区不变</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git reset [commit]</span><br></pre></td></tr></table></figure>
</li>
<li><p>重置当前分支的HEAD为指定 commit,同时重置暂存区和工作区,与指定 commit 一致</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git reset --hard [commit]</span><br></pre></td></tr></table></figure>
</li>
<li><p>新建一个 commit,用于撤销指定 commit</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git revert [commit]</span><br></pre></td></tr></table></figure>
</li>
<li><p>将未提交的变化放在储藏区</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git stash</span><br></pre></td></tr></table></figure>
</li>
<li><p>将储藏区的内容恢复到当前工作区(stash被删除)</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git stash pop</span><br></pre></td></tr></table></figure>
</li>
<li><p>将储藏区的内容恢复到当前工作区(stash未被删除)</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git stash apply</span><br></pre></td></tr></table></figure>
</li>
<li><p>将stash后的内容上删除</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git stash drop</span><br></pre></td></tr></table></figure>
</li>
<li><p>恢复某个stash</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git stash apply stash@{0}</span><br></pre></td></tr></table></figure>
</li>
</ul>
<blockquote>
<p>查询</p>
</blockquote>
<ul>
<li><p>查看工作区文件修改状态</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git status</span><br></pre></td></tr></table></figure>
</li>
<li><p>查看工作区文件修改具体内容 </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git diff [file]</span><br></pre></td></tr></table></figure>
</li>
<li><p>查看暂存区文件修改内容</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git diff --cached [file]</span><br></pre></td></tr></table></figure>
</li>
<li><p>查看版本库修改记录</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git log</span><br></pre></td></tr></table></figure>
</li>
<li><p>查带表日志</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git log --graph --pretty=oneline --abbrev-commit</span><br></pre></td></tr></table></figure>
</li>
<li><p>可以查看分支合并吐</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git log --graph</span><br></pre></td></tr></table></figure>
</li>
<li><p>查看某人提交记录</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git log --author=someone</span><br></pre></td></tr></table></figure>
</li>
<li><p>查看某个文件的历史具体修改内容</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git log -p [file]</span><br></pre></td></tr></table></figure>
</li>
<li><p>查看某次提交具体修改内容</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git show [commit]</span><br></pre></td></tr></table></figure>
</li>
</ul>
<blockquote>
<p>添加</p>
</blockquote>
<ul>
<li><p>关联本地于远程仓库</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git remote add origin [remote-name]</span><br></pre></td></tr></table></figure>
</li>
<li><p>推送本地仓库到远程仓库</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git push -u origin master</span><br></pre></td></tr></table></figure>
</li>
</ul>
<blockquote>
<p>Merge</p>
</blockquote>
<ul>
<li><p>分支合并带分支合并记录</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git merge --no-ff -m "merge with no-ff" dev</span><br></pre></td></tr></table></figure>
</li>
</ul>
<blockquote>
<p>Tag</p>
</blockquote>
<ul>
<li><p>创建Tag</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git tag v1.0</span><br></pre></td></tr></table></figure>
</li>
<li><p>创建Tag 带说明</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git tag -a v0.1 -m "This is v0.1 tag" 1fcc775</span><br></pre></td></tr></table></figure>
</li>
<li><p>查看某个tag信息</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git show v1.0</span><br></pre></td></tr></table></figure>
</li>
<li><p>查看所有tag</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git tag</span><br></pre></td></tr></table></figure>
</li>
<li><p>删除某个tag</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git tag -d v1.0</span><br></pre></td></tr></table></figure>
</li>
<li><p>从本地把创建的tag推到远程</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git push origin v1.0</span><br></pre></td></tr></table></figure>
</li>
<li><p>一次性推送全部尚未推送到远程的本地标签</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git push origin —tags</span><br></pre></td></tr></table></figure>
</li>
<li><p>删除远程标签</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git tag -d v1.0</span><br><span class="line">git push origin:refs/tags/v1.0</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h3 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h3><ul>
<li><p><a href="http://gitbook.liuhui998.com/index.html" target="_blank" rel="noopener">中文教程</a></p>
</li>
<li><p><a href="https://git-scm.com/book/zh/v2" target="_blank" rel="noopener">英文教程</a></p>
</li>
<li><p><a href="https://www.liaoxuefeng.com/wiki/896043488029600" target="_blank" rel="noopener">廖大神教程</a></p>
</li>
</ul>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/11/11/iOS-accumulate/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar_myself.jpeg">
<meta itemprop="name" content="coyeli">
<meta itemprop="description" content="一名移动端开发者,但不限于移动端端技术(学无止境...)">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="记录过程">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a href="/2018/11/11/iOS-accumulate/" class="post-title-link" itemprop="url">iOS 积累</a>
</h1>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2018-11-11 11:11:11" itemprop="dateCreated datePublished" datetime="2018-11-11T11:11:11+08:00">2018-11-11</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-check-o"></i>
</span>
<span class="post-meta-item-text">更新于</span>
<time title="修改时间:2019-11-06 14:39:24" itemprop="dateModified" datetime="2019-11-06T14:39:24+08:00">2019-11-06</time>
</span>
<span class="post-meta-item">
<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/iOS/" itemprop="url" rel="index">
<span itemprop="name">iOS</span>
</a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h3 id="编译"><a href="#编译" class="headerlink" title="编译"></a>编译</h3><ul>
<li><a href="https://mp.weixin.qq.com/s/aqjiFExhPIb4f7thke3r8Q" target="_blank" rel="noopener">理解 Xcode 编译系统</a></li>
</ul>
<h3 id="逆向"><a href="#逆向" class="headerlink" title="逆向"></a>逆向</h3><ul>
<li><p><a href="https://mp.weixin.qq.com/s?__biz=MjM5NTQ2NzE0NQ==&mid=2247483817&idx=1&sn=9088b0d9b74c9c32e410e7cd74d7498e&chksm=a6f95b4f918ed259e502a87716267ebe29211cb18efe6e46569447479c0d2b32a4130f6760ac&scene=21#wechat_redirect" target="_blank" rel="noopener">iOS逆向基础Mach-O文件(1</a></p>
</li>
<li><p><a href="https://mp.weixin.qq.com/s/df9OWuMHnRVkcO64QfGh4w" target="_blank" rel="noopener">iOS逆向基础砸壳原理(2)</a></p>
</li>
<li><p><a href="https://mp.weixin.qq.com/s/GJyR-mp7uKvNR3LfPC55Hg" target="_blank" rel="noopener">iOS逆向基础动态库注入实现过程(三</a></p>
</li>
<li><p><a href="https://mp.weixin.qq.com/s/vRRTY0x0AwWhyKXK8rxhZA" target="_blank" rel="noopener">iOS逆向基础Hopper+LLDB调试(四)</a></p>
</li>
<li><p><a href="https://objccn.io/issue-6-3/" target="_blank" rel="noopener">Mach-O 可执行文件</a></p>
</li>
<li><p><a href="https://www.jianshu.com/p/1b9ca38b8b9f" target="_blank" rel="noopener">dyld加载应用启动原理详解</a> </p>
</li>
</ul>
<h3 id="签名"><a href="#签名" class="headerlink" title="签名"></a>签名</h3><ul>
<li><p><a href="http://blog.cnbang.net/tech/3386/" target="_blank" rel="noopener">iOS App 签名的原理</a></p>
</li>
<li><p><a href="https://www.jianshu.com/p/7d5daf6436b2" target="_blank" rel="noopener">shell脚本实现iOS包重签名及代码注入</a> </p>
</li>
</ul>
<h3 id="性能优化"><a href="#性能优化" class="headerlink" title="性能优化"></a>性能优化</h3><ul>
<li><p><a href="https://mp.weixin.qq.com/s/Kf3EbDIUuf0aWVT-UCEmbA" target="_blank" rel="noopener">iOS App 启动性能优化</a></p>
</li>
<li><p><a href="https://juejin.im/post/5da830a4e51d457805049817" target="_blank" rel="noopener">了解App的启动流程</a></p>
</li>
<li><p><a href="https://www.jianshu.com/p/526b9308e741" target="_blank" rel="noopener">使用“Time Profiler”工具监控App的启动耗时</a> </p>
</li>
<li><p><a href="https://blog.cnbang.net/tech/3477/" target="_blank" rel="noopener">移动 H5 首屏秒开优化方案探讨</a></p>
</li>
</ul>
<h3 id="Crash"><a href="#Crash" class="headerlink" title="Crash"></a>Crash</h3><ul>
<li><p><a href="https://www.jianshu.com/p/6a12e9d92366" target="_blank" rel="noopener">Crash 防护系统』(一)Unrecognized Selector</a></p>
</li>
<li><p><a href="https://www.jianshu.com/p/e3713d309283" target="_blank" rel="noopener">『Crash 防护系统』(二)KVO 防护</a></p>
</li>
<li><p><a href="https://www.jianshu.com/p/db273418f67c" target="_blank" rel="noopener">『Crash 防护系统』(三)KVC 防护</a></p>
</li>
</ul>
<h3 id="内存管理"><a href="#内存管理" class="headerlink" title="内存管理"></a>内存管理</h3><ul>
<li><a href="https://mp.weixin.qq.com/s/P2F6QvZQpnrA5O3RKAU-Rg" target="_blank" rel="noopener">关于 AutoreleasePool,你可能漏了这几点</a></li>
</ul>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block home" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/12/hexo-question/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar_myself.jpeg">
<meta itemprop="name" content="coyeli">
<meta itemprop="description" content="一名移动端开发者,但不限于移动端端技术(学无止境...)">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="记录过程">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">