/
index.html
493 lines (347 loc) · 27.3 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
<!DOCTYPE HTML>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>用CocoaPods做iOS程序的依赖管理 | 唐巧的博客</title>
<meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=no">
<meta name="author" content="唐巧">
<meta name="description" content="文档更新说明 2012-12-02 v1.0 初稿 2014-01-08 v1.1 增加设置 ruby 淘宝源相关内容 2014-05-25 v2.0 增加国内 spec 镜像、使用私有 pod、podfile.lock、创建 spec 文件等内容 2015-09-03 v2.1 优化排版,调整一些描述方式,使文章更易读懂。 2015-12-21 v2.2 将淘宝的镜像修改成 https 的。">
<meta property="og:type" content="article">
<meta property="og:title" content="用CocoaPods做iOS程序的依赖管理">
<meta property="og:url" content="https://blog.devtang.com/2014/05/25/use-cocoapod-to-manage-ios-lib-dependency/index.html">
<meta property="og:site_name" content="唐巧的博客">
<meta property="og:description" content="文档更新说明 2012-12-02 v1.0 初稿 2014-01-08 v1.1 增加设置 ruby 淘宝源相关内容 2014-05-25 v2.0 增加国内 spec 镜像、使用私有 pod、podfile.lock、创建 spec 文件等内容 2015-09-03 v2.1 优化排版,调整一些描述方式,使文章更易读懂。 2015-12-21 v2.2 将淘宝的镜像修改成 https 的。">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://blog.devtang.com/images/cocoapods-logo.png">
<meta property="article:published_time" content="2014-05-25T06:09:00.000Z">
<meta property="article:modified_time" content="2020-02-08T18:08:22.157Z">
<meta property="article:author" content="唐巧">
<meta property="article:tag" content="iOS">
<meta property="article:tag" content="唐巧">
<meta property="article:tag" content="猿辅导">
<meta property="article:tag" content="开发">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://blog.devtang.com/images/cocoapods-logo.png">
<link rel="alternative" href="/atom.xml" title="唐巧的博客" type="application/atom+xml">
<link rel="icon" href="/img/favicon.png">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/%02.css">
<link rel="stylesheet" href="/.css">
<meta name="generator" content="Hexo 4.2.0"></head>
<body>
<header>
<div>
<div id="textlogo">
<h1 class="site-name"><a href="/" title="唐巧的博客">唐巧的博客</a></h1>
<h2 class="blog-motto">记录下自己学习的点滴</h2>
</div>
<div class="navbar"><a class="navbutton navmobile" href="#" title="菜单">
</a></div>
<nav class="animated">
<ul>
<ul>
<li><a href="/">首页</a></li>
<li><a href="/archives">归档</a></li>
<li><a href="/about">关于</a></li>
<li>
<form class="search" action="//google.com/search" method="get" accept-charset="utf-8">
<label>Search</label>
<input type="search" id="search" name="q" autocomplete="off" maxlength="20" placeholder="搜索" />
<input type="hidden" name="q" value="site:blog.devtang.com">
</form>
</li>
</ul>
</nav>
</div>
</header>
<div id="container">
<div id="main" class="post" itemscope itemprop="blogPost">
<article itemprop="articleBody">
<header class="article-info clearfix">
<h1 itemprop="name">
<a href="/2014/05/25/use-cocoapod-to-manage-ios-lib-dependency/" title="用CocoaPods做iOS程序的依赖管理" itemprop="url">用CocoaPods做iOS程序的依赖管理</a>
</h1>
<p class="article-time">
<time datetime="2014-05-25T06:09:00.000Z" itemprop="datePublished"> 发表于 2014-05-25 06:09</time>
</p>
</header>
<div class="article-content">
<div id="toc" class="toc-article">
<strong class="toc-title">文章目录</strong>
<ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#文档更新说明"><span class="toc-number">1.</span> <span class="toc-text">文档更新说明</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#CocoaPods-简介"><span class="toc-number">2.</span> <span class="toc-text">CocoaPods 简介</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#CocoaPods-的安装和使用介绍"><span class="toc-number">3.</span> <span class="toc-text">CocoaPods 的安装和使用介绍</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#安装"><span class="toc-number">3.1.</span> <span class="toc-text">安装</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#使用-CocoaPods-的镜像索引"><span class="toc-number">3.2.</span> <span class="toc-text">使用 CocoaPods 的镜像索引</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#使用-CocoaPods"><span class="toc-number">3.3.</span> <span class="toc-text">使用 CocoaPods</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#查找第三方库"><span class="toc-number">3.4.</span> <span class="toc-text">查找第三方库</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#关于-Podfile-lock"><span class="toc-number">3.5.</span> <span class="toc-text">关于 Podfile.lock</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#为自己的项目创建-podspec-文件"><span class="toc-number">4.</span> <span class="toc-text">为自己的项目创建 podspec 文件</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#使用私有的-pods"><span class="toc-number">5.</span> <span class="toc-text">使用私有的 pods</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#不更新-podspec"><span class="toc-number">6.</span> <span class="toc-text">不更新 podspec</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#生成第三方库的帮助文档"><span class="toc-number">6.1.</span> <span class="toc-text">生成第三方库的帮助文档</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#原理"><span class="toc-number">7.</span> <span class="toc-text">原理</span></a></li></ol>
</div>
<img src="/images/cocoapods-logo.png" class="">
<h2 id="文档更新说明"><a href="#文档更新说明" class="headerlink" title="文档更新说明"></a>文档更新说明</h2><ul>
<li>2012-12-02 v1.0 初稿</li>
<li>2014-01-08 v1.1 增加设置 ruby 淘宝源相关内容</li>
<li>2014-05-25 v2.0 增加国内 spec 镜像、使用私有 pod、podfile.lock、创建 spec 文件等内容</li>
<li>2015-09-03 v2.1 优化排版,调整一些描述方式,使文章更易读懂。</li>
<li>2015-12-21 v2.2 将淘宝的镜像修改成 https 的。</li>
</ul>
<h2 id="CocoaPods-简介"><a href="#CocoaPods-简介" class="headerlink" title="CocoaPods 简介"></a>CocoaPods 简介</h2><p>每种语言发展到一个阶段,就会出现相应的依赖管理工具,例如 Java 语言的 Maven,nodejs 的 npm。随着 iOS 开发者的增多,业界也出现了为 iOS 程序提供依赖管理的工具,它的名字叫做:<a href="http://cocoapods.org/" target="_blank" rel="noopener">CocoaPods</a>。</p>
<p>CocoaPods<a href="https://github.com/CocoaPods/CocoaPods" target="_blank" rel="noopener">项目的源码</a> 在 Github 上管理。该项目开始于 2011 年 8 月 12 日,经过多年发展,现在已经成为 iOS 开发事实上的依赖管理标准工具。开发 iOS 项目不可避免地要使用第三方开源库,CocoaPods 的出现使得我们可以节省设置和更新第三方开源库的时间。</p>
<p>我在开发猿题库客户端时,使用了 24 个第三方开源库。在没有使用 CocoaPods 以前,我需要:</p>
<ol>
<li>把这些第三方开源库的源代码文件复制到项目中,或者设置成 git 的 submodule。</li>
<li>对于这些开源库通常需要依赖系统的一些 framework,我需要手工地将这些 framework 分别增加到项目依赖中,比如通常情况下,一个网络库就需要增加以下 framework: CFNetwork, SystemConfiguration, MobileCoreServices, CoreGraphics, zlib。</li>
<li>对于某些开源库,我还需要设置<code>-licucore</code>或者 <code>-fno-objc-arc</code>等编译参数</li>
<li>管理这些依赖包的更新。</li>
</ol>
<p>这些体力活虽然简单,但毫无技术含量并且浪费时间。在使用 CocoaPods 之后,我只需要将用到的第三方开源库放到一个名为 Podfile 的文件中,然后执行<code>pod install</code>。<br>CocoaPods 就会自动将这些第三方开源库的源码下载下来,并且为我的工程设置好相应的系统依赖和编译参数。</p>
<h2 id="CocoaPods-的安装和使用介绍"><a href="#CocoaPods-的安装和使用介绍" class="headerlink" title="CocoaPods 的安装和使用介绍"></a>CocoaPods 的安装和使用介绍</h2><h3 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h3><p>安装方式异常简单 , Mac 下都自带 ruby,使用 ruby 的 gem 命令即可下载安装:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">$ sudo gem install cocoapods</span><br><span class="line">$ pod setup</span><br></pre></td></tr></table></figure>
<p>如果你的 gem 太老,可能也会有问题,可以尝试用如下命令升级 gem:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sudo gem update --system</span><br></pre></td></tr></table></figure>
<p>另外,ruby 的软件源 <a href="https://rubygems.org" target="_blank" rel="noopener">https://rubygems.org</a> 因为使用的是亚马逊的云服务,所以被墙了,需要更新一下 ruby 的源,使用如下代码将官方的 ruby 源替换成国内淘宝的源:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">gem sources --remove https://rubygems.org/</span><br><span class="line">gem sources -a https://ruby.taobao.org/</span><br><span class="line">gem sources -l</span><br></pre></td></tr></table></figure>
<p>还有一点需要注意,<code>pod setup</code>在执行时,会输出<code>Setting up CocoaPods master repo</code>,但是会等待比较久的时间。这步其实是 Cocoapods 在将它的信息下载到 <code>~/.cocoapods</code>目录下,如果你等太久,可以试着 cd 到那个目录,用<code>du -sh *</code>来查看下载进度。你也可以参考本文接下来的<code>使用 cocoapods 的镜像索引</code>一节的内容来提高下载速度。</p>
<h3 id="使用-CocoaPods-的镜像索引"><a href="#使用-CocoaPods-的镜像索引" class="headerlink" title="使用 CocoaPods 的镜像索引"></a>使用 CocoaPods 的镜像索引</h3><p>所有的项目的 Podspec 文件都托管在<code>https://github.com/CocoaPods/Specs</code>。第一次执行<code>pod setup</code>时,CocoaPods 会将这些<code>podspec</code>索引文件更新到本地的 <code>~/.cocoapods/</code>目录下,这个索引文件比较大,有 80M 左右。所以第一次更新时非常慢,笔者就更新了将近 1 个小时才完成。</p>
<p>一个叫 <a href="http://akinliu.github.io/2014/05/03/cocoapods-specs-/" target="_blank" rel="noopener">akinliu</a> 的朋友在 <a href="http://gitcafe.com/" target="_blank" rel="noopener">gitcafe</a> 和 <a href="http://www.oschina.net/" target="_blank" rel="noopener">oschina</a> 上建立了 CocoaPods 索引库的镜像,因为 gitcafe 和 oschina 都是国内的服务器,所以在执行索引更新操作时,会快很多。如下操作可以将 CocoaPods 设置成使用 gitcafe 镜像:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line">pod repo remove master</span><br><span class="line">pod repo add master https://gitcafe.com/akuandev/Specs.git</span><br><span class="line">pod repo update</span><br></pre></td></tr></table></figure>
<p>将以上代码中的 <code>https://gitcafe.com/akuandev/Specs.git</code> 替换成 <code>http://git.oschina.net/akuandev/Specs.git</code> 即可使用 oschina 上的镜像。</p>
<h3 id="使用-CocoaPods"><a href="#使用-CocoaPods" class="headerlink" title="使用 CocoaPods"></a>使用 CocoaPods</h3><p>使用时需要新建一个名为 Podfile 的文件,以如下格式,将依赖的库名字依次列在文件中即可</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">platform :ios</span><br><span class="line">pod 'JSONKit', '~> 1.4'</span><br><span class="line">pod 'Reachability', '~> 3.0.0'</span><br><span class="line">pod 'ASIHTTPRequest'</span><br><span class="line">pod 'RegexKitLite'</span><br></pre></td></tr></table></figure>
<p>然后你将编辑好的 Podfile 文件放到你的项目根目录中,执行如下命令即可:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">cd</span> <span class="string">"your project home"</span></span><br><span class="line">pod install</span><br></pre></td></tr></table></figure>
<p>现在,你的所有第三方库都已经下载完成并且设置好了编译参数和依赖,你只需要记住如下 2 点即可:</p>
<ol>
<li>使用 CocoaPods 生成的 *.xcworkspace 文件来打开工程,而不是以前的 *.xcodeproj 文件。</li>
<li>每次更改了 Podfile 文件,你需要重新执行一次<code>pod update</code>命令。</li>
</ol>
<h3 id="查找第三方库"><a href="#查找第三方库" class="headerlink" title="查找第三方库"></a>查找第三方库</h3><p>你如果不知道 cocoaPods 管理的库中,是否有你想要的库,那么你可以通过 pod search 命令进行查找,以下是我用 pod search json 查找到的所有可用的库:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">$ pod search json</span><br><span class="line"></span><br><span class="line">-> AnyJSON (0.0.1)</span><br><span class="line"> Encode / Decode JSON by any means possible.</span><br><span class="line"> - Homepage: https://github.com/mattt/AnyJSON</span><br><span class="line"> - Source: https://github.com/mattt/AnyJSON.git</span><br><span class="line"> - Versions: 0.0.1 [master repo]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">-> JSONKit (1.5pre)</span><br><span class="line"> A Very High Performance Objective-C JSON Library.</span><br><span class="line"> - Homepage: https://github.com/johnezang/JSONKit</span><br><span class="line"> - Source: git://github.com/johnezang/JSONKit.git</span><br><span class="line"> - Versions: 1.5pre, 1.4 [master repo]</span><br><span class="line"></span><br><span class="line">// ... 以下省略若干行</span><br></pre></td></tr></table></figure>
<h3 id="关于-Podfile-lock"><a href="#关于-Podfile-lock" class="headerlink" title="关于 Podfile.lock"></a>关于 Podfile.lock</h3><p>当你执行<code>pod install</code>之后,除了 Podfile 外,CocoaPods 还会生成一个名为<code>Podfile.lock</code>的文件,Podfile.lock 应该加入到版本控制里面,不应该把这个文件加入到<code>.gitignore</code>中。因为<code>Podfile.lock</code>会锁定当前各依赖库的版本,之后如果多次执行<code>pod install</code> 不会更改版本,要<code>pod update</code>才会改<code>Podfile.lock</code>了。这样多人协作的时候,可以防止第三方库升级时造成大家各自的第三方库版本不一致。</p>
<p>CocoaPods 的这篇 <a href="http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control" target="_blank" rel="noopener">官方文档</a> 也在<code>What is a Podfile.lock</code>一节中介绍了<code>Podfile.lock</code>的作用,并且指出:</p>
<blockquote><p>This file should always be kept under version control.</p>
</blockquote>
<h2 id="为自己的项目创建-podspec-文件"><a href="#为自己的项目创建-podspec-文件" class="headerlink" title="为自己的项目创建 podspec 文件"></a>为自己的项目创建 podspec 文件</h2><p>我们可以为自己的开源项目创建<code>podspec</code>文件,首先通过如下命令初始化一个<code>podspec</code>文件:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">pod spec create your_pod_spec_name</span><br></pre></td></tr></table></figure>
<p>该命令执行之后,CocoaPods 会生成一个名为<code>your_pod_spec_name.podspec</code>的文件,然后我们修改其中的相关内容即可。</p>
<p>具体步骤可以参考这两篇博文中的相关内容:</p>
<ul>
<li><a href="http://ishalou.com/blog/2012/10/16/how-to-create-a-cocoapods-spec-file/" target="_blank" rel="noopener">《如何编写一个 CocoaPods 的 spec 文件》</a> </li>
<li><a href="http://studentdeng.github.io/blog/2013/09/13/cocoapods-tutorial/" target="_blank" rel="noopener">《Cocoapods 入门》</a>。</li>
</ul>
<h2 id="使用私有的-pods"><a href="#使用私有的-pods" class="headerlink" title="使用私有的 pods"></a>使用私有的 pods</h2><p>我们可以直接指定某一个依赖的<code>podspec</code>,这样就可以使用公司内部的私有库。该方案有利于使企业内部的公共项目支持 CocoaPods。如下是一个示例:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">pod <span class="string">'MyCommon'</span>, :podspec => <span class="string">'https://yuantiku.com/common/myCommon.podspec'</span></span><br></pre></td></tr></table></figure>
<h2 id="不更新-podspec"><a href="#不更新-podspec" class="headerlink" title="不更新 podspec"></a>不更新 podspec</h2><p>CocoaPods 在执行<code>pod install</code>和<code>pod update</code>时,会默认先更新一次<code>podspec</code>索引。使用<code>--no-repo-update</code>参数可以禁止其做索引更新操作。如下所示:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">pod install --no-repo-update</span><br><span class="line">pod update --no-repo-update</span><br></pre></td></tr></table></figure>
<h3 id="生成第三方库的帮助文档"><a href="#生成第三方库的帮助文档" class="headerlink" title="生成第三方库的帮助文档"></a>生成第三方库的帮助文档</h3><p>如果你想让 CococaPods 帮你生成第三方库的帮助文档,并集成到 Xcode 中,那么用 brew 安装 appledoc 即可:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">brew install appledoc</span><br></pre></td></tr></table></figure>
<p>关于 appledoc,我在另一篇博客 <a href="/2012/02/01/use-appledoc-to-generate-xcode-doc/">《使用 Objective-C 的文档生成工具:appledoc》</a> 中有专门介绍。它最大的优点是可以将帮助文档集成到 Xcode 中,这样你在敲代码的时候,按住 opt 键单击类名或方法名,就可以显示出相应的帮助文档。</p>
<h2 id="原理"><a href="#原理" class="headerlink" title="原理"></a>原理</h2><p>大概研究了一下 CocoaPods 的原理,它是将所有的依赖库都放到另一个名为 Pods 项目中,然后让主项目依赖 Pods 项目,这样,源码管理工作都从主项目移到了 Pods 项目中。发现的一些技术细节有:</p>
<ol>
<li>Pods 项目最终会编译成一个名为 libPods.a 的文件,主项目只需要依赖这个 .a 文件即可。</li>
<li>对于资源文件,CocoaPods 提供了一个名为 Pods-resources.sh 的 bash 脚本,该脚本在每次项目编译的时候都会执行,将第三方库的各种资源文件复制到目标目录中。</li>
<li>CocoaPods 通过一个名为 Pods.xcconfig 的文件来在编译时设置所有的依赖和参数。</li>
</ol>
<p>愿大家玩得开心~</p>
</div>
<footer class="article-footer clearfix">
<div class="article-catetags">
<div class="article-categories">
<span></span>
<a class="article-category-link" href="/categories/iOS/">iOS</a>
</div>
</div>
<div class="article-share" id="share">
<div data-url="https://blog.devtang.com/2014/05/25/use-cocoapod-to-manage-ios-lib-dependency/" data-title="用CocoaPods做iOS程序的依赖管理 | 唐巧的博客" data-tsina="" class="share clearfix">
</div>
</div>
</footer>
</article>
<nav class="article-nav clearfix">
<div class="prev" >
<a href="/2014/05/30/understand-tagged-pointer/" title="深入理解Tagged Pointer">
<strong>上一篇:</strong><br/>
<span>
深入理解Tagged Pointer</span>
</a>
</div>
<div class="next">
<a href="/2014/05/23/how-to-persist-writing/" title="技术人员如何坚持写作">
<strong>下一篇:</strong><br/>
<span>技术人员如何坚持写作
</span>
</a>
</div>
</nav>
</div>
<div class="openaside"><a class="navbutton" href="#" title="显示侧边栏"></a></div>
<div id="asidepart">
<div class="closeaside"><a class="closebutton" href="#" title="隐藏侧边栏"></a></div>
<aside class="clearfix">
<div class="sponsor">
</div>
<div class="categorieslist">
<p class="asidetitle">分类</p>
<ul>
<li><a href="/categories/books-summary/" title="books summary">books summary</a></li>
<li><a href="/categories/iOS/" title="iOS">iOS</a></li>
<li><a href="/categories/iOS-weekly/" title="iOS weekly">iOS weekly</a></li>
<li><a href="/categories/mac/" title="mac">mac</a></li>
<li><a href="/categories/shell/" title="shell">shell</a></li>
<li><a href="/categories/summary/" title="summary">summary</a></li>
</ul>
</div>
<div class="weixin">
<br />
<p class="asidetitle">微信公众号</p>
<p>关注我的微信公众号,和我一起成长:</p>
<img src="/images/weixin-qr.jpg" width="230px" />
</div>
<div class="rsspart">
<a href="/atom.xml" target="_blank" title="rss">RSS 订阅</a>
</div>
</aside>
</div>
</div>
<footer><div id="footer" >
<div class="social-font" class="clearfix">
</div>
<p class="copyright" style="margin-top: 10px;">
Powered by <a href="http://hexo.io" target="_blank" title="hexo">hexo</a> and Theme by <a href="https://github.com/wuchong/jacman" target="_blank" title="Jacman">Jacman</a> © 2020
<a href="/about" target="_blank" title="唐巧">唐巧</a>
</p>
</div>
</footer>
<script src="/js/jquery-2.0.3.min.js"></script>
<script src="/js/jquery.imagesloaded.min.js"></script>
<script src="/js/gallery.js"></script>
<script src="/js/jquery.qrcode-0.12.0.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('.navbar').click(function(){
$('header nav').toggleClass('shownav');
});
var myWidth = 0;
function getSize(){
if( typeof( window.innerWidth ) == 'number' ) {
myWidth = window.innerWidth;
} else if( document.documentElement && document.documentElement.clientWidth) {
myWidth = document.documentElement.clientWidth;
};
};
var m = $('#main'),
a = $('#asidepart'),
c = $('.closeaside'),
o = $('.openaside');
c.click(function(){
a.addClass('fadeOut').css('display', 'none');
o.css('display', 'block').addClass('fadeIn');
m.addClass('moveMain');
});
o.click(function(){
o.css('display', 'none').removeClass('beforeFadeIn');
a.css('display', 'block').removeClass('fadeOut').addClass('fadeIn');
m.removeClass('moveMain');
});
$(window).scroll(function(){
o.css("top",Math.max(80,260-$(this).scrollTop()));
});
$(window).resize(function(){
getSize();
if (myWidth >= 1024) {
$('header nav').removeClass('shownav');
}else{
m.removeClass('moveMain');
a.css('display', 'block').removeClass('fadeOut');
o.css('display', 'none');
}
});
});
</script>
<script type="text/javascript">
$(document).ready(function(){
var ai = $('.article-content>iframe'),
ae = $('.article-content>embed'),
t = $('#toc'),
ta = $('#toc.toc-aside'),
o = $('.openaside'),
c = $('.closeaside');
if(ai.length>0){
ai.wrap('<div class="video-container" />');
};
if(ae.length>0){
ae.wrap('<div class="video-container" />');
};
c.click(function(){
ta.css('display', 'block').addClass('fadeIn');
});
o.click(function(){
ta.css('display', 'none');
});
$(window).scroll(function(){
ta.css("top",Math.max(140,320-$(this).scrollTop()));
});
});
</script>
<script type="text/javascript">
$(document).ready(function(){
var $this = $('.share'),
url = $this.attr('data-url'),
encodedUrl = encodeURIComponent(url),
title = $this.attr('data-title'),
tsina = $this.attr('data-tsina'),
description = $this.attr('description');
var html = [
'<div class="hoverqrcode clearfix"></div>',
'<a class="overlay" id="qrcode"></a>',
'<a href="https://www.facebook.com/sharer.php?u=' + encodedUrl + '" class="article-share-facebook" target="_blank" title="Facebook"></a>',
'<a href="https://twitter.com/intent/tweet?url=' + encodedUrl + '" class="article-share-twitter" target="_blank" title="Twitter"></a>',
'<a href="#qrcode" class="article-share-qrcode" title="微信"></a>',
'<a href="http://widget.renren.com/dialog/share?resourceUrl=' + encodedUrl + '&srcUrl=' + encodedUrl + '&title=' + title +'" class="article-share-renren" target="_blank" title="人人"></a>',
'<a href="http://service.weibo.com/share/share.php?title='+title+'&url='+encodedUrl +'&ralateUid='+ tsina +'&searchPic=true&style=number' +'" class="article-share-weibo" target="_blank" title="微博"></a>',
'<span title="Share to"></span>'
].join('');
$this.append(html);
$('.hoverqrcode').hide();
var myWidth = 0;
function updatehoverqrcode(){
if( typeof( window.innerWidth ) == 'number' ) {
myWidth = window.innerWidth;
} else if( document.documentElement && document.documentElement.clientWidth) {
myWidth = document.documentElement.clientWidth;
};
var qrsize = myWidth > 1024 ? 200:100;
var options = {render: 'image', size: qrsize, fill: '#2ca6cb', text: url, radius: 0.5, quiet: 1};
var p = $('.article-share-qrcode').position();
$('.hoverqrcode').empty().css('width', qrsize).css('height', qrsize)
.css('left', p.left-qrsize/2+20).css('top', p.top-qrsize-10)
.qrcode(options);
};
$(window).resize(function(){
$('.hoverqrcode').hide();
});
$('.article-share-qrcode').click(function(){
updatehoverqrcode();
$('.hoverqrcode').toggle();
});
$('.article-share-qrcode').hover(function(){}, function(){
$('.hoverqrcode').hide();
});
});
</script>
<!-- Analytics Begin -->
<script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-28029597-1', '');
ga('send', 'pageview');
</script>
<!-- Analytics End -->
<!-- Totop Begin -->
<div id="totop">
<a title="返回顶部"><img src="/img/scrollup.png"/></a>
</div>
<script src="/js/totop.js"></script>
<!-- Totop End -->
<!-- MathJax Begin -->
<!-- mathjax config similar to math.stackexchange -->
<!-- MathJax End -->
<!-- Tiny_search Begin -->
<!-- Tiny_search End -->
</body>
</html>