-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
354 lines (195 loc) · 98.3 KB
/
atom.xml
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
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>wenbobao's blog</title>
<link href="/atom.xml" rel="self"/>
<link href="http://blog.wenbobao.cn/"/>
<updated>2017-12-26T16:08:24.000Z</updated>
<id>http://blog.wenbobao.cn/</id>
<author>
<name>wenbobao</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>iOS项目中集成KSCrash</title>
<link href="http://blog.wenbobao.cn/2017/03/15/iOS%E9%A1%B9%E7%9B%AE%E4%B8%AD%E9%9B%86%E6%88%90KSCrash%20/"/>
<id>http://blog.wenbobao.cn/2017/03/15/iOS项目中集成KSCrash /</id>
<published>2017-03-15T07:00:16.000Z</published>
<updated>2017-12-26T16:08:24.000Z</updated>
<content type="html"><![CDATA[<h1 id="项目地址"><a href="#项目地址" class="headerlink" title="项目地址:"></a>项目地址:</h1><p><a href="https://github.com/kstenerud/KSCrash" target="_blank" rel="noopener">https://github.com/kstenerud/KSCrash</a></p><h1 id="How-to-Use-KSCrash"><a href="#How-to-Use-KSCrash" class="headerlink" title="How to Use KSCrash"></a>How to Use KSCrash</h1><ol><li><p>Add the framework to your project (or add the KSCrash project as a dependency)</p></li><li><p>Add the following system frameworks & libraries to your project:<br> libc++.dylib<br> libz.dylib<br> MessageUI.framework (iOS only)<br> SystemConfiguration.framework</p></li><li><p>Add the flag “-ObjC” to Other Linker Flags in your Build Settings</p></li><li><p>Add the following to your [application: didFinishLaunchingWithOptions:] method in your app delegate:</p></li></ol><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><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line">#import <KSCrash/KSCrash.h></span><br><span class="line">// Include to use the standard reporter.</span><br><span class="line">#import <KSCrash/KSCrashInstallationStandard.h></span><br><span class="line">// Include to use Quincy or Hockey.</span><br><span class="line">#import <KSCrash/KSCrashInstallationQuincyHockey.h></span><br><span class="line">// Include to use the email reporter.</span><br><span class="line">#import <KSCrash/KSCrashInstallationEmail.h></span><br><span class="line">// Include to use Victory.</span><br><span class="line">#import <KSCrash/KSCrashInstallationVictory.h></span><br><span class="line"></span><br><span class="line">- (BOOL)application:(UIApplication*) application didFinishLaunchingWithOptions:(NSDictionary*) launchOptions</span><br><span class="line">{</span><br><span class="line">KSCrashInstallationStandard* installation = [KSCrashInstallationStandard sharedInstance];</span><br><span class="line">installation.url = [NSURL URLWithString:@"http://put.your.url.here"];</span><br><span class="line"></span><br><span class="line">// OR:</span><br><span class="line"></span><br><span class="line">KSCrashInstallationQuincy* installation = [KSCrashInstallationQuincy sharedInstance];</span><br><span class="line">installation.url = [NSURL URLWithString:@"http://put.your.url.here"];</span><br><span class="line"></span><br><span class="line">// OR:</span><br><span class="line"></span><br><span class="line">KSCrashInstallationHockey* installation = [KSCrashInstallationHockey sharedInstance];</span><br><span class="line">installation.appIdentifier = @"PUT_YOUR_HOCKEY_APP_ID_HERE";</span><br><span class="line"></span><br><span class="line">// OR:</span><br><span class="line"></span><br><span class="line">KSCrashInstallationEmail* installation = [KSCrashInstallationEmail sharedInstance];</span><br><span class="line">installation.recipients = @[@"some@email.address"];</span><br><span class="line"></span><br><span class="line">// Optional (Email): Send Apple-style reports instead of JSON</span><br><span class="line">[installation setReportStyle:KSCrashEmailReportStyleApple useDefaultFilenameFormat:YES]; </span><br><span class="line"></span><br><span class="line">// Optional: Add an alert confirmation (recommended for email installation)</span><br><span class="line">[installation addConditionalAlertWithTitle:@"Crash Detected"</span><br><span class="line"> message:@"The app crashed last time it was launched. Send a crash report?"</span><br><span class="line"> yesAnswer:@"Sure!"</span><br><span class="line"> noAnswer:@"No thanks"];</span><br><span class="line"></span><br><span class="line">// OR:</span><br><span class="line"></span><br><span class="line">KSCrashInstallationVictory* installation = [KSCrashInstallationVictory sharedInstance];</span><br><span class="line">installation.url = [NSURL URLWithString:@"https://put.your.url.here/api/v1/crash/<application key>"];</span><br><span class="line"></span><br><span class="line">[installation install];</span><br><span class="line"> …</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">// last: </span><br><span class="line">[installation sendAllReportsWithCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error)</span><br><span class="line">{</span><br><span class="line"> // Stuff to do when report sending is complete</span><br><span class="line">}];</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h1 id="项目地址"><a href="#项目地址" class="headerlink" title="项目地址:"></a>项目地址:</h1><p><a href="https://github.com/kstenerud/KSCrash" target="_blan
</summary>
<category term="KSCrash" scheme="http://blog.wenbobao.cn/tags/KSCrash/"/>
</entry>
<entry>
<title>远程启动jboss,关闭窗口,jboss自动关闭</title>
<link href="http://blog.wenbobao.cn/2016/08/17/2016-08-17/"/>
<id>http://blog.wenbobao.cn/2016/08/17/2016-08-17/</id>
<published>2016-08-17T07:55:21.000Z</published>
<updated>2017-12-26T16:09:30.000Z</updated>
<content type="html"><![CDATA[<p>问题描述:<br>java环境: jdk1.6, jboss4.2<br>远程ssh启动jboss ./run.sh -b xx.xx.xx.xx &,可以正常访问<br>关闭ssh窗口,不能访问<br>解决方案: </p><ol><li>先exit退出服务器,断开连接,再关闭ssh窗口.</li><li>直接用nohup启动jboss服务</li></ol>]]></content>
<summary type="html">
<p>问题描述:<br>java环境: jdk1.6, jboss4.2<br>远程ssh启动jboss ./run.sh -b xx.xx.xx.xx &amp;,可以正常访问<br>关闭ssh窗口,不能访问<br>解决方案: </p>
<ol>
<li>先exit退出服务器
</summary>
<category term="服务器 jboss" scheme="http://blog.wenbobao.cn/tags/%E6%9C%8D%E5%8A%A1%E5%99%A8-jboss/"/>
</entry>
<entry>
<title>iOS + Jenkins + SVN 自动化打包配置</title>
<link href="http://blog.wenbobao.cn/2016/04/11/iOS_Jenkins_SVN%E8%87%AA%E5%8A%A8%E5%8C%96%E6%89%93%E5%8C%85%E9%85%8D%E7%BD%AE/"/>
<id>http://blog.wenbobao.cn/2016/04/11/iOS_Jenkins_SVN自动化打包配置/</id>
<published>2016-04-11T08:36:20.000Z</published>
<updated>2017-12-26T16:08:54.000Z</updated>
<content type="html"><![CDATA[<h2 id="环境"><a href="#环境" class="headerlink" title="环境"></a>环境</h2><ol><li>下载Jenkins.war<br> <a href="https://jenkins.io/download/" target="_blank" rel="noopener">https://jenkins.io/download/</a></li><li>JDK 1.80</li><li>tomcat7.0</li></ol><h2 id="步骤"><a href="#步骤" class="headerlink" title="步骤"></a>步骤</h2><ul><li>将jenkins.war部署到tomcat中,启动tomcat</li><li>浏览器中输入 <a href="http://localhost:8080/jenkins/" target="_blank" rel="noopener">http://localhost:8080/jenkins/</a></li><li><p>安装jenkins插件</p><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></pre></td><td class="code"><pre><span class="line">1. Xcode integration: iOS专用</span><br><span class="line">2. Keychains and Provisioning Profiles Management</span><br><span class="line">3. Subversion Plug-in SVN </span><br><span class="line">4. SSH Credentials Plugin (可选)</span><br><span class="line">5. build-name-setter:用于修改Build名称 (可选)</span><br><span class="line">6. description setter plugin:用于在修改Build描述信息,在描述信息中增加显示QRCode(二维码)(可选)</span><br><span class="line">7. Post-Build Script Plug-in:在编译完成后通过执行脚本实现一些额外功能 (可选)</span><br></pre></td></tr></table></figure></li><li><p>系统管理 -> 系统设置将 Subversion Workspace Version 设置为1.7</p></li><li><p>系统管理 -> Keychains and Provisioning Profiles Management -> 上传 keychain & mobileprovision</p><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">注意 :</span><br><span class="line">1. 这里keychain 是将p12文件直接改后缀名为keychain (a.p12 -> a.keychain)</span><br><span class="line">2. mobileprovision 的 Provisioning Profiles Directory Path 设置为 ${PROVISIONING_PROFILE}</span><br></pre></td></tr></table></figure></li></ul><ul><li>新建 -> 一个自由风格的项目 -> <code>DEMO_V1.0_UAT</code></li></ul><p>配置项目:</p><ul><li>General -> 丢弃旧的构建</li></ul><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">1. 保持构建的天数 -> 10</span><br><span class="line">2. 保持构建的最大个数 -> 15</span><br></pre></td></tr></table></figure><ul><li><p>源码管理 -> Subversion</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">1. Repository URL -> SVN Path</span><br><span class="line">2. Credentials -> 添加SVN账户,密码,描述</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">1. Keychains and Code Signing Identities</span><br><span class="line">2. Mobile Provisioning Profiles</span><br></pre></td></tr></table></figure></li></ul><ul><li><p>构建 -> Execute shell</p><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></pre></td><td class="code"><pre><span class="line">echo 'package' | sudo -S xcode-select --switch /Applications/Xcode8.2.app/Contents/Developer</span><br><span class="line">unzip -o $WORKSPACE/3party/ZIP/XX.zip -d $WORKSPACE/3party/ZIP/</span><br><span class="line">nowtime=`date +%Y%m%d%H`</span><br><span class="line">/usr/libexec/PlistBuddy -c "Set:CFBundleVersion $nowtime" $WORKSPACE/DEMO/Info.plist</span><br><span class="line">/usr/libexec/PlistBuddy -c "Set:CFBundleDisplayName DEMO UAT 1.0" $WORKSPACE/DEMO/Info.plist</span><br></pre></td></tr></table></figure></li></ul><ul><li><p>构建 -> Xcode -> General build setting </p><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></pre></td><td class="code"><pre><span class="line">1. Target -> (输入项目的Target)</span><br><span class="line">2. Setting -> 勾选 Clean before build?</span><br><span class="line">3. Configuration -> Release</span><br><span class="line">4. .ipa filename pattern -> XX_IOS_${JOB_NAME}_${VERSION}</span><br><span class="line">5. Output directory -> $WORKSPACE/build_outputs/${BUILD_TAG}</span><br><span class="line">6. Manifest Plist URL -> $WORKSPACE/build_outputs/${BUILD_TAG}</span><br></pre></td></tr></table></figure></li></ul><ul><li>如果项目使用cocoapods,需要配置 Advanced Xcode build options </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">1. Xcode Schema File -> (Schema的名字)</span><br><span class="line">2. SYMROOT -> ${WORKSPACE}/build</span><br><span class="line">3. Xcode Workspace File -> (Workspace的名字)</span><br></pre></td></tr></table></figure><ul><li>构建后操作 -> Archive the artifacts </li></ul><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">1. 用于存档的文件 -> build_outputs/${BUILD_TAG}/*.ipa,build_outputs/${BUILD_TAG}/*.plist</span><br><span class="line">2. 高级设置 -> 选择1,2,4,5</span><br></pre></td></tr></table></figure><h2 id="安全设置"><a href="#安全设置" class="headerlink" title="安全设置"></a>安全设置</h2><p>系统管理 -> Configure Global Security</p><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">1. 安全域 -> 勾选(Jenkins专有用户数据库) -> 允许用户注册</span><br><span class="line">2. 授权策略 -> 勾选(项目矩阵授权策略)-> 添加用户 (1. 管理员账户 全部勾选 2. 匿名用户 勾选 Read)</span><br><span class="line">3. 在项目配置文件中 -> General -> 启用项目安全 -> 添加用户</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="环境"><a href="#环境" class="headerlink" title="环境"></a>环境</h2><ol>
<li>下载Jenkins.war<br> <a href="https://jenkins.io/download/" target=
</summary>
<category term="Jenkins" scheme="http://blog.wenbobao.cn/tags/Jenkins/"/>
</entry>
<entry>
<title>给iOS应用增加3DTouch功能</title>
<link href="http://blog.wenbobao.cn/2016/03/11/%E7%BB%99iOS%E5%BA%94%E7%94%A8%E5%A2%9E%E5%8A%A03DTouch%E5%8A%9F%E8%83%BD/"/>
<id>http://blog.wenbobao.cn/2016/03/11/给iOS应用增加3DTouch功能/</id>
<published>2016-03-11T08:58:30.000Z</published>
<updated>2017-12-26T14:07:26.000Z</updated>
<content type="html"><![CDATA[<h2 id="3D-Touch-的主要应用"><a href="#3D-Touch-的主要应用" class="headerlink" title="3D Touch 的主要应用"></a>3D Touch 的主要应用</h2><ol><li>A user can now press your Home screen icon to immediately access functionality provided by your app.</li></ol><h2 id="3D-Touch-的三大模块"><a href="#3D-Touch-的三大模块" class="headerlink" title="3D Touch 的三大模块"></a>3D Touch 的三大模块</h2><ol><li>Home Screen Quick Actions</li><li>peek and pop</li><li><p>Force Properties</p><h2 id="Home-Screen-Quick-Action使用与相关api详解"><a href="#Home-Screen-Quick-Action使用与相关api详解" class="headerlink" title="Home Screen Quick Action使用与相关api详解"></a>Home Screen Quick Action使用与相关api详解</h2><p> iOS9为我们提供了两种屏幕标签,分别是静态标签和动态标签。 </p></li></ol><h3 id="静态标签"><a href="#静态标签" class="headerlink" title="静态标签"></a>静态标签</h3><pre><code>所谓静态快捷方式,就是在应用安装前预先设置好的不能够改变的菜单项,它的设置方式是在 Info.plist 里面添加一个 UIApplicationShortcutItems 字段(系统没有提示,只能手打上去),如下图</code></pre><p><img src="http://ww2.sinaimg.cn/large/65b80fc9jw1f1w6we9mayj20we08itc6.jpg" alt=""></p><p>UIApplicationShortcutItems 为数组类型,里面的每一个数组项代表快捷菜单上面的一个菜单项。</p><p>每一个菜单项都有下面几个属性。示例:</p><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></pre></td><td class="code"><pre><span class="line"><dict></span><br><span class="line"><key>UIApplicationShortcutItemIconType</key></span><br><span class="line"><string>UIApplicationShortcutIconTypeAudio</string></span><br><span class="line"><key>UIApplicationShortcutItemTitle</key></span><br><span class="line"><string>音乐</string></span><br><span class="line"><key>UIApplicationShortcutItemType</key></span><br><span class="line"><string>$(PRODUCT_BUNDLE_IDENTIFIER).First</string></span><br><span class="line"><key>UIApplicationShortcutItemUserInfo</key></span><br><span class="line"><dict></span><br><span class="line"><key>firstShorcutKey1</key></span><br><span class="line"><string>firstShortcutKeyValue1</string></span><br><span class="line"></dict></span><br><span class="line"></dict></span><br></pre></td></tr></table></figure><ul><li><p>(必须)UIApplicationShortcutItemType:这个选项表示这个菜单项的唯一标识。</p></li><li><p>(必须)UIApplicationShortcutItemTitle:这个选项表示菜单项显示的标题。</p></li><li><p>(可选)UIApplicationShortcutItemSubtitle:这个表示菜单项的子标题。</p></li><li><p>(可选)UIApplicationShortcutItemIconType:这个属性表示菜单的图标,系统自带的图标。</p></li><li><p>(可选)UIApplicationShortcutItemIconFile:这个属性表示菜单图标的文件名,可以使用自定义的图标。</p></li><li><p>(可选)UIApplicationShortcutItemUserInfo:这个代表了菜单项点击后,传入的用户信息,也是可选的。</p></li></ul><p>效果如下:</p><p><img src="http://ww3.sinaimg.cn/large/65b80fc9jw1f1w705k3ybj20i80gogn3.jpg" alt=""></p><h3 id="动态标签"><a href="#动态标签" class="headerlink" title="动态标签"></a>动态标签</h3><p>动态标签是我们在程序中,通过代码添加的,与之相关的类,主要有三个:</p><p>UIApplicationShortcutItem 创建3DTouch标签的类</p><p>UIMutableApplicationShortcutItem 创建可变的3DTouch标签的类</p><p>UIApplicationShortcutIcon 创建标签中图片Icon的类</p><p>3、响应标签的行为</p><p>类似推送,当我们点击标签进入应用程序时,也可以进行一些操作,我们可以看到,在applocation中增加了这样一个方法: </p><ul><li>( void )application:( UIApplication <em>)application performActionForShortcutItem:(UIApplicationShortcutItem </em>)shortcutItem completionHandler:( void (^)( BOOLsucceeded))completionHandler NS_AVAILABLE_IOS ( 9 _0);</li></ul><p>当我们通过标签进入app时,就会在appdelegate中调用这样一个回调,我们可以获取shortcutItem的信息进行相关逻辑操作。</p><p>这里有一点需要注意:我们在app的入口函数:</p><ul><li>( BOOL )application:( UIApplication <em>)application didFinishLaunchingWithOptions:( NSDictionary </em>)launchOptions;</li></ul><p>也需要进行一下判断,在launchOptions中有UIApplicationLaunchOptionsShortcutItemKey这样一个键,通过它,我们可以区别是否是从标签进入的app,如果是则处理结束逻辑后,返回NO,防止处理逻辑被反复回调。</p><p>几点注意:</p><p>1、快捷标签最多可以创建四个,包括静态的和动态的。</p><p>2、每个标签的题目和icon最多两行,多出的会用…省略</p><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ol><li><a href="https://developer.apple.com/ios/3d-touch/" target="_blank" rel="noopener">苹果官方文档</a></li><li><a href="http://www.jianshu.com/p/2920d2f74fb4" target="_blank" rel="noopener">iOS9 3D touch 适配开发</a></li><li><a href="http://www.cocoachina.com/ios/20151019/13812.html" target="_blank" rel="noopener">iOS 9 新特性之实现 3D Touch 就是 So easy</a></li><li><a href="http://my.oschina.net/SoulJa/blog/525680" target="_blank" rel="noopener">iOS 3D Touch功能</a></li><li><a href="http://www.cocoachina.com/ios/20151021/13849.html" target="_blank" rel="noopener">在iPhone上使用3D Touch</a></li><li><a href="http://blog.csdn.net/showhilllee/article/details/48376073" target="_blank" rel="noopener">iOS9 3DTouch、ShortcutItem、Peek And Pop技术一览</a></li><li><a href="http://blog.csdn.net/liwenjie0912/article/details/49178873" target="_blank" rel="noopener"> iOS 3D Touch (UIApplicationShortcutItem、UIViewControllerPreviewing、UIPreviewAction)</a></li><li><a href="http://www.it165.net/pro/html/201510/54990.html" target="_blank" rel="noopener">iOS 指压即达 如何集成iOS9里的3D Touch</a></li><li><a href="http://blog.devzeng.com/blog/ios9-3d-touch.html" target="_blank" rel="noopener">在iOS9中使用3D Touch</a></li><li><a href="http://www.jianshu.com/p/3443a3b27b2d" target="_blank" rel="noopener">iOS开发之3D Touch</a></li><li><a href="http://www.jianshu.com/p/c32d286c1bf7" target="_blank" rel="noopener">iOS9 新特征之3D Touch实现</a></li><li><a href="http://www.jianshu.com/p/ab9c6b09cb66" target="_blank" rel="noopener">3D Touch</a></li><li><a href="http://www.07net01.com/program/2016/01/1196145.html" target="_blank" rel="noopener">iOS 3D Touch开发tableview页面内的使用</a></li><li><a href="http://www.ithao123.cn/content-10689481.html" target="_blank" rel="noopener">ios 3D Touch功能的实现</a></li><li><a href="http://laurenz.io/2015/10/ios-9-uitableview-how-to-peek-and-pop-in-to-table-cells-with-3d-touch/" target="_blank" rel="noopener">iOS 9 UITableView – How to “Peek and Pop” in to table cells with 3D touch?</a></li><li><a href="http://useyourloaf.com/blog/3d-touch-peek-and-pop/" target="_blank" rel="noopener">3D Touch Peek and Pop</a></li><li><a href="http://code.tutsplus.com/tutorials/ios-9-an-introduction-to-3d-touch--cms-25115" target="_blank" rel="noopener">iOS 9: An Introduction to 3D Touch</a></li></ol>]]></content>
<summary type="html">
<h2 id="3D-Touch-的主要应用"><a href="#3D-Touch-的主要应用" class="headerlink" title="3D Touch 的主要应用"></a>3D Touch 的主要应用</h2><ol>
<li>A user can now p
</summary>
<category term="3DTouch" scheme="http://blog.wenbobao.cn/tags/3DTouch/"/>
</entry>
<entry>
<title>iOS远程推送</title>
<link href="http://blog.wenbobao.cn/2015/10/11/iOS%E8%BF%9C%E7%A8%8B%E6%8E%A8%E9%80%81/"/>
<id>http://blog.wenbobao.cn/2015/10/11/iOS远程推送/</id>
<published>2015-10-11T08:58:30.000Z</published>
<updated>2017-12-26T14:07:26.000Z</updated>
<content type="html"><![CDATA[<p>iOS中有两类消息推送方式</p><ol><li>本地通知</li><li>远程推送</li></ol><h2 id="远程推送的响应"><a href="#远程推送的响应" class="headerlink" title="远程推送的响应"></a>远程推送的响应</h2><p>这里分为两种情况</p><h3 id="app关闭"><a href="#app关闭" class="headerlink" title="app关闭"></a>app关闭</h3><p>在app关闭时,通过本地通知进入app,不会触发application:didReceiveLocalNotification方法. 需要通过application: didFinishLaunchingWithOptions:方法, 判断是否由本地通知打开app</p><h3 id="app没有关闭"><a href="#app没有关闭" class="headerlink" title="app没有关闭"></a>app没有关闭</h3><p>在app没有关闭时,又分为2种情况:</p><ol><li>app在前台运行,此时会自动触发 application:didReceiveLocalNotification方法</li><li>app在后台运行,此时当用户点击通知图标时会触发application:didReceiveLocalNotification方法。</li></ol><p>当app没有关闭(后台运行), 调用本地通知启动<br><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></pre></td><td class="code"><pre><span class="line">// 本地通知回调函数,当应用程序在前台时调用 </span><br><span class="line">- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { </span><br><span class="line"> NSLog(@"noti:%@",notification); </span><br><span class="line"></span><br><span class="line"> // 这里真实需要处理交互的地方 </span><br><span class="line"> // 获取通知所带的数据 </span><br><span class="line"> NSString *notMess = [notification.userInfo objectForKey:@"key"]; </span><br><span class="line"> UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"本地通知(前台)" </span><br><span class="line"> message:notMess </span><br><span class="line"> delegate:nil </span><br><span class="line"> cancelButtonTitle:@"OK" </span><br><span class="line"> otherButtonTitles:nil]; </span><br><span class="line"> [alert show]; </span><br><span class="line"></span><br><span class="line"> // 更新显示的徽章个数 </span><br><span class="line"> NSInteger badge = [UIApplication sharedApplication].applicationIconBadgeNumber; </span><br><span class="line"> badge--; </span><br><span class="line"> badge = badge >= 0 ? badge : 0; </span><br><span class="line"> [UIApplication sharedApplication].applicationIconBadgeNumber = badge; </span><br><span class="line"></span><br><span class="line"> // 在不需要再推送时,可以取消推送 </span><br><span class="line"> [HomeViewController cancelLocalNotificationWithKey:@"key"]; </span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><p>当app关闭, 调用本地通知启动<br><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></pre></td><td class="code"><pre><span class="line">- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {</span><br><span class="line"></span><br><span class="line"> //app启动时,其他代码</span><br><span class="line"> [self otherCode];</span><br><span class="line"></span><br><span class="line"> /*本地通知方式-启动*/</span><br><span class="line"> //获取本地通知,如果不是本地通知方式启动, notification将为nil</span><br><span class="line"> UILocalNotification *notification = [launchOptions objectForKey: UIApplicationLaunchOptionsLocalNotificationKey];</span><br><span class="line"> if (notification && [notification isKindOfClass:[UILocalNotification class]]) {</span><br><span class="line"> //获取本地通知详细信息</span><br><span class="line"> NSDictionary *userInfo = notification.userInfo;</span><br><span class="line"> //通过信息判断为哪条本地通知, 做出相应回应</span><br><span class="line"> NSString *name = [userInfo objectForKey:@"name"];</span><br><span class="line"> if ([name isEqualToString:@"remindNotification"]) {</span><br><span class="line"> //做出反应</span><br><span class="line"> [self actionCode];</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> return YES;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p><h2 id="注意"><a href="#注意" class="headerlink" title="注意"></a>注意</h2><ul><li>iOS最多允许本地通知的数量是64个,超过限制的本地通知将被iOS忽略。</li><li>在iOS8之后,添加本地通知,需要用[UIApplication registerUserNotificationSettings:]去注册通知 </li></ul><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ul><li><a href="http://blog.csdn.net/daiyibo123/article/details/48435219" target="_blank" rel="noopener">iOS-本地推送(本地通知)</a></li><li><a href="http://blog.sina.com.cn/s/blog_9564cb6e0102w77g.html" target="_blank" rel="noopener">ios本地通知UILocalNotification以及区分谁触发了通知(转)</a></li><li><a href="http://blog.sina.com.cn/s/blog_b29d0ec90102vkx2.html" target="_blank" rel="noopener">Ios开发中UILocalNotification实现本地通知实现提醒功能</a></li></ul>]]></content>
<summary type="html">
<p>iOS中有两类消息推送方式</p>
<ol>
<li>本地通知</li>
<li>远程推送</li>
</ol>
<h2 id="远程推送的响应"><a href="#远程推送的响应" class="headerlink" title="远程推送的响应"></a>远程推送的
</summary>
<category term="UILocalNotification" scheme="http://blog.wenbobao.cn/tags/UILocalNotification/"/>
</entry>
<entry>
<title>iOS项目中workspace,project,targe,scheme之间的关系</title>
<link href="http://blog.wenbobao.cn/2015/09/19/2015-09-19/"/>
<id>http://blog.wenbobao.cn/2015/09/19/2015-09-19/</id>
<published>2015-09-19T05:33:04.000Z</published>
<updated>2017-12-26T14:07:26.000Z</updated>
<content type="html"><![CDATA[<h2 id="workspace"><a href="#workspace" class="headerlink" title="workspace"></a>workspace</h2><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">A workspace is an Xcode document that groups projects and other documents so you can work on them together. </span><br><span class="line">A workspace can contain any number of Xcode projects, plus any other files you want to include. </span><br><span class="line">In addition to organizing all the files in each Xcode project, a workspace provides implicit and explicit relationships among the included projects and their targets.</span><br></pre></td></tr></table></figure><ol><li>workspace可以包含多个project,同时管理不同的project之间的关系。</li><li>workspace 是以 xcworkspace 的文件形式存在。</li><li>workspace解决了原来仅有 project 的时候不同的 project 之间的引用和调用困难的问题。</li><li>使用cocopods时会生成workspace。</li><li>不同的 project 就是一个个的组件,workspace 把他们组装在一起,project 相互之间独立又有联系。(有的 project 之间可能会有依赖关系)</li><li>一个 workspace 的 多个 project共用一个编译路径。</li></ol><h2 id="Project"><a href="#Project" class="headerlink" title="Project"></a>Project</h2><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></pre></td><td class="code"><pre><span class="line">An Xcode project is a repository for all the files, resources, and information required to build one or more software products. </span><br><span class="line">A project contains all the elements used to build your products and maintains the relationships between those elements. </span><br><span class="line">It contains one or more targets, which specify how to build products. </span><br><span class="line">A project defines default build settings for all the targets in the project (each target can also specify its own build settings, which override the project build settings)</span><br></pre></td></tr></table></figure><ol><li>project里面包含了所有的源文件</li><li>project可以包含很多个Target</li><li>project声明了项目默认的配置,target可以重写其配置,实现不同的配置</li></ol><h2 id="Target"><a href="#Target" class="headerlink" title="Target"></a>Target</h2><ol><li>一个target对应一个plist文件,在plist文件中可以设置项目名称,bundle ID ,版本号,资源文件等</li><li>target 和 target 之间没有关联,一个Target对应一个配置。</li><li>target和project之间有关联,target的 Build Settings 会从 project 的 Build Settings 继承一部分属性</li><li>可以在现有的target右键copy,创建新的target,创建target之后需要修改scheme的名字与之对应。</li></ol><h2 id="Scheme"><a href="#Scheme" class="headerlink" title="Scheme"></a>Scheme</h2><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">You use Xcode schemes to specify which target, build configuration, and executable configuration is active at a given time.</span><br><span class="line">An Xcode scheme defines a collection of targets to build, a configuration to use when building, and a collection of tests to execute.</span><br></pre></td></tr></table></figure><ol><li>scheme 是用来决定运行哪个target </li><li>一般就是一个 scheme 对应着一个 target</li><li>可以针对编译,运行,单元测试,动态分析,静态代码分析以及打包进行一些配置。</li></ol><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><ul><li>怎么查看项目中的Targets,Build Configurations,Schemes?终端运行命令:</li></ul><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">xcodebuild -list</span><br></pre></td></tr></table></figure><ul><li>怎么创建Target?</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">1. 新建项目,在现有target右键copy创建新的target</span><br><span class="line">2. 修改plist文件名字及其路径</span><br><span class="line">3. 修改scheme名字</span><br></pre></td></tr></table></figure><ul><li>怎么在项目中中获取当前运行的是哪个target?</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><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">1. 在SIT target -> Build Settings -> LLVM Custom Compiler Flags -> Other C Flags 设置 -DTARGET_SIT</span><br><span class="line">2. 在UAT target -> Build Settings -> LLVM Custom Compiler Flags -> Other C Flags 设置 -DTARGET_UAT</span><br><span class="line">3. 在PROD target -> Build Settings -> LLVM Custom Compiler Flags -> Other C Flags 设置 -DTARGET_PROD</span><br><span class="line">4. 项目中 用下面的code</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line">#if defined (TARGET_SIT)</span><br><span class="line"> NSLog(@"target sit");</span><br><span class="line">#elif defined (TARGET_UAT)</span><br><span class="line"> NSLog(@"target uat");</span><br><span class="line">#else</span><br><span class="line"> NSLog(@"target prod");</span><br><span class="line">#endif</span><br></pre></td></tr></table></figure><ul><li>怎么在项目中中获取当前运行的是哪个build configurations?</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">1. project -> Info -> Configurations -> add New Configurations</span><br><span class="line">2. project-> Build Settings -> LLVM Preprocessing -> Preprocessor Macros -> PROD -> 设置为 -> PROD=1</span><br><span class="line">3. 项目中 用下面的code</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line">#if defined (PROD)</span><br><span class="line"> NSLog(@"scheme PROD");</span><br><span class="line">#elif defined (UAT)</span><br><span class="line"> NSLog(@"scheme uat");</span><br><span class="line">#else</span><br><span class="line"> NSLog(@"scheme sit");</span><br><span class="line">#endif</span><br></pre></td></tr></table></figure><ul><li>项目中有多个target,怎么写cocoapods?</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><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></pre></td><td class="code"><pre><span class="line">def pods</span><br><span class="line"> pod ‘AFNetworking’ </span><br><span class="line">end</span><br><span class="line"></span><br><span class="line">platform :ios, ‘8.0’</span><br><span class="line"></span><br><span class="line">target 'DEMO_SIT' do</span><br><span class="line"> # use_frameworks!</span><br><span class="line"> pods</span><br><span class="line">end</span><br><span class="line"></span><br><span class="line">target 'DEMO_UAT’ do</span><br><span class="line"> # use_frameworks!</span><br><span class="line"> pods</span><br><span class="line">end</span><br><span class="line"></span><br><span class="line">target 'DEMO_PROD’ do</span><br><span class="line"> # use_frameworks!</span><br><span class="line"> pods </span><br><span class="line">end</span><br></pre></td></tr></table></figure><ul><li>项目中添加了文件,运行时提示找不到文件怎么办?</li></ul><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">1. 删掉文件索引</span><br><span class="line">2. 重新加入文件,记得勾选所有的target</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="workspace"><a href="#workspace" class="headerlink" title="workspace"></a>workspace</h2><figure class="highlight plain"><table><tr><t
</summary>
</entry>
<entry>
<title>线程安全的FMDatabaseQueue</title>
<link href="http://blog.wenbobao.cn/2015/06/11/%E7%A8%8B%E5%AE%89%E5%85%A8%E7%9A%84FMDatabaseQueue/"/>
<id>http://blog.wenbobao.cn/2015/06/11/程安全的FMDatabaseQueue/</id>
<published>2015-06-11T02:11:29.000Z</published>
<updated>2017-12-26T16:07:29.000Z</updated>
<content type="html"><![CDATA[<h2 id="为什么使用FMDatabaseQueue"><a href="#为什么使用FMDatabaseQueue" class="headerlink" title="为什么使用FMDatabaseQueue"></a>为什么使用FMDatabaseQueue</h2><p>在实际的项目运行过程中,我们常常会遇到同一时刻有多个不同的线程请求数据库的访问。<br>举个简单的例子:</p><blockquote><p>假设当前线程1正在写数据库A,这时,线程2正好也要写数据库A,如果没有做线程安全处理,会造成很多数据没有如预期写入数据库。</p><p>假设当前线程1正在写数据库A,这时,线程2正好要读数据库A,如果没有做线程安全处理,会报”database is locked”错误。</p></blockquote><p>FMDB是对sqlite的封装,而文件数据库sqlite在同一时刻允许多个进程/线程读,但同一时刻只允许一个线程写。在进行写操作时,数据库文件会被琐定,此时任何其他读/写操作都被阻塞,如果阻塞超过5秒钟(默认是5秒,重新编译sqlite可以修改超时时间),就报”database is locked”错误。 </p><p>如果线程使用单独的FMDatabase 实例是允许的,但是在多线程的环境下,不能多个线程共享一个FMDatabase对象,这样可能会造成数据的操作丢失,甚至引起程序的崩溃。</p><p>那么怎么做线程安全呢?使用FMDatabaseQueue。</p><p>FMDatabaseQueue可以比较有效的解决多线程下对数据库的访问,但是请注意不能在多个线程同时创建多个FMDatabaseQueue实例来操作同一个数据库。下面我们看下FMDatabaseQueue的用法和实现原理。</p><h2 id="FMDatabaseQueue用法"><a href="#FMDatabaseQueue用法" class="headerlink" title="FMDatabaseQueue用法"></a>FMDatabaseQueue用法</h2><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">FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];</span><br></pre></td></tr></table></figure><p>使用</p><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></pre></td><td class="code"><pre><span class="line">[queue inDatabase:^(FMDatabase *db) {</span><br><span class="line"> [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @1];</span><br><span class="line"> [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @2];</span><br><span class="line"> [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @3];</span><br><span class="line"></span><br><span class="line"> FMResultSet *rs = [db executeQuery:@"select * from foo"];</span><br><span class="line"> while ([rs next]) {</span><br><span class="line"> …</span><br><span class="line"> }</span><br><span class="line">}];</span><br></pre></td></tr></table></figure><p>支持事务</p><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></pre></td><td class="code"><pre><span class="line">[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {</span><br><span class="line"> [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @1];</span><br><span class="line"> [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @2];</span><br><span class="line"> [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @3];</span><br><span class="line"></span><br><span class="line"> if (whoopsSomethingWrongHappened) {</span><br><span class="line"> *rollback = YES;</span><br><span class="line"> return;</span><br><span class="line"> }</span><br><span class="line"> // etc…</span><br><span class="line"> [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @4];</span><br><span class="line">}];</span><br></pre></td></tr></table></figure><h2 id="FMDatabaseQueue实现原理"><a href="#FMDatabaseQueue实现原理" class="headerlink" title="FMDatabaseQueue实现原理"></a>FMDatabaseQueue实现原理</h2><p>FMDatabaseQueue通过内部创建一个Serial的dispatch_queue_t,来处理通过inDatabase和inTransaction传入的Blocks,会按顺序来执行它接收的Blocks。所以当我们在主线程(或者后台)调用inDatabase或者inTransaction时,代码实际上是同步的。</p><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></pre></td><td class="code"><pre><span class="line">_queue = dispatch_queue_create([[NSString stringWithFormat:@"fmdb.%@", self] UTF8String], NULL);</span><br><span class="line">- (void)inDatabase:(void (^)(FMDatabase *db))block {</span><br><span class="line"> //省略部分代码 </span><br><span class="line"> dispatch_sync(_queue, ^() {</span><br><span class="line"> FMDatabase *db = [self database];</span><br><span class="line"> block(db);</span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line"> FMDBRelease(self);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>FMDatabaseQueue这么设计的目的是让我们避免发生并发访问数据库的问题,因为对数据库的访问可能是随机的(在任何时候)、不同线程间(不同的网络回调等)的。内置一个Serial队列后,FMDatabaseQueue就变成线程安全了,所有的数据库访问都是同步执行,而且这比使用@synchronized或NSLock要高效得多。</p><h2 id="特殊情况"><a href="#特殊情况" class="headerlink" title="特殊情况"></a>特殊情况</h2><p>如果在后台执行大量的更新操作时,主线程又需要执行少量的数据库操作(比如查询),那么在后台操作执行完之前,它还是需要等待,这时就会阻塞主线程。下面是一些参考意见:</p><ul><li>如果在后台使用inDatabase来更新大批量的数据时,可以考虑使用inTransaction,因为后者的更新效率高很多,特别是更新大量操作(如1000条以上)</li><li>如果非必须一次性的、完整性的大批量数据,可以考虑使用数据拆解,将大量数据分成较多批少量的数据,再进行更新操作,这样能有效地避免长时间的阻塞</li><li>如果UI上不需要在更新数据时产生交互,可以将FMDatabaseQueue放入一个子线程中异步执行,这是一个不错的选择,反之,就需要考虑UI上的体验了,如加上一个UIActivityIndicatorView。</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><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{</span><br><span class="line"> [self.databaseQueue inDatabase:^(FMDatabase *db) {</span><br><span class="line"> // do something ...</span><br><span class="line"> }];</span><br><span class="line">});</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="为什么使用FMDatabaseQueue"><a href="#为什么使用FMDatabaseQueue" class="headerlink" title="为什么使用FMDatabaseQueue"></a>为什么使用FMDatabaseQueue</h2><
</summary>
<category term="FMDB" scheme="http://blog.wenbobao.cn/tags/FMDB/"/>
</entry>
<entry>
<title>sqlite常用命令查询</title>
<link href="http://blog.wenbobao.cn/2015/05/16/sqlite%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4%E6%9F%A5%E8%AF%A2/"/>
<id>http://blog.wenbobao.cn/2015/05/16/sqlite常用命令查询/</id>
<published>2015-05-16T04:35:09.000Z</published>
<updated>2017-12-26T16:07:57.000Z</updated>
<content type="html"><![CDATA[<h2 id="创建表"><a href="#创建表" class="headerlink" title="创建表"></a>创建表</h2><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></pre></td><td class="code"><pre><span class="line">CREATE TABLE COMPANY(</span><br><span class="line"> ID INT PRIMARY KEY NOT NULL,</span><br><span class="line"> NAME TEXT NOT NULL,</span><br><span class="line"> AGE INT NOT NULL,</span><br><span class="line"> ADDRESS CHAR(50),</span><br><span class="line"> SALARY REAL</span><br><span class="line">);</span><br></pre></td></tr></table></figure><h2 id="删除表"><a href="#删除表" class="headerlink" title="删除表"></a>删除表</h2><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">DROP TABLE table_name;</span><br></pre></td></tr></table></figure><h2 id="Insert-语句"><a href="#Insert-语句" class="headerlink" title="Insert 语句"></a>Insert 语句</h2><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">INSERT INTO TABLE_NAME (column1, column2, column3,...columnN)] </span><br><span class="line">VALUES (value1, value2, value3,...valueN);</span><br><span class="line">```</span><br></pre></td></tr></table></figure><p>INSERT INTO TABLE_NAME VALUES (value1,value2,value3,…valueN);<br><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"></span><br><span class="line">## Select 语句</span><br></pre></td></tr></table></figure></p><p>SELECT * FROM table_name;<br><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">```</span><br><span class="line">SELECT column1, column2, columnN FROM table_name;</span><br></pre></td></tr></table></figure></p><h2 id="运算符"><a href="#运算符" class="headerlink" title="运算符"></a>运算符</h2><p> 比较运算符</p><ul><li>== </li><li>=</li><li>!=</li><li><></li><li>></li><li><</li><li><blockquote><p>=</p></blockquote></li><li><=</li><li>!<</li><li>!></li></ul><p>逻辑运算符</p><ul><li>AND</li><li>BETWEEN</li><li>EXISTS</li><li>IN</li><li>NOT IN</li><li>LIKE</li><li>GLOB</li><li>NOT</li><li>OR</li><li>IS NULL</li><li>IS</li><li>IS NOT</li><li>||</li><li>UNIQUE</li></ul><h2 id="Update-语句"><a href="#Update-语句" class="headerlink" title="Update 语句"></a>Update 语句</h2> <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">UPDATE table_name</span><br><span class="line">SET column1 = value1, column2 = value2...., columnN = valueN</span><br><span class="line">WHERE [condition];</span><br></pre></td></tr></table></figure><h2 id="Delete-语句"><a href="#Delete-语句" class="headerlink" title="Delete 语句"></a>Delete 语句</h2><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">DELETE FROM table_name</span><br><span class="line">WHERE [condition];</span><br></pre></td></tr></table></figure><p>注: 使用 SQLite 的 DELETE 可以 删除全部的数据,但建议使用 DROP TABLE 命令删除整个表,然后再重新创建一遍。</p><h2 id="Where-子句"><a href="#Where-子句" class="headerlink" title="Where 子句"></a>Where 子句</h2><h2 id="Like-子句"><a href="#Like-子句" class="headerlink" title="Like 子句"></a>Like 子句</h2><p>% 代表零个、一个或多个数字<br>_ 代表一个单一的数字或字符</p><h2 id="Limit-子句"><a href="#Limit-子句" class="headerlink" title="Limit 子句"></a>Limit 子句</h2><p>限制了您想要从表中提取的行数</p><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">SELECT column1, column2, columnN </span><br><span class="line">FROM table_name</span><br><span class="line">LIMIT 6</span><br></pre></td></tr></table></figure><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">SELECT * FROM COMPANY LIMIT 3 OFFSET 2;</span><br></pre></td></tr></table></figure><h2 id="Order-By-排序"><a href="#Order-By-排序" class="headerlink" title="Order By (排序)"></a>Order By (排序)</h2><ul><li>ASC 升序</li><li>DES 降序</li></ul><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">SELECT * FROM COMPANY ORDER BY NAME DESC;</span><br></pre></td></tr></table></figure><p>##Group By(分组)</p><p>SQLite 的 GROUP BY 子句用于与 SELECT 语句一起使用,来对相同的数据进行分组。</p><p><code>注意 GROUP BY 子句放在 WHERE 子句之后,放在 ORDER BY 子句之前。</code></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">SELECT NAME, SUM(SALARY) FROM COMPANY GROUP BY NAME ORDER BY NAME DESC</span><br></pre></td></tr></table></figure><h2 id="Having-子句"><a href="#Having-子句" class="headerlink" title="Having 子句"></a>Having 子句</h2><p>HAVING 子句允许指定条件来过滤将出现在最终结果中的分组结果。<br>WHERE 子句在所选列上设置条件,而 HAVING 子句则在由 GROUP BY 子句创建的分组上设置条件。</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">SELECT * FROM COMPANY GROUP BY name HAVING count(name) < 2;</span><br></pre></td></tr></table></figure><h2 id="Distinct-关键字"><a href="#Distinct-关键字" class="headerlink" title="Distinct 关键字"></a>Distinct 关键字</h2><p>SQLite 的 DISTINCT 关键字与 SELECT 语句一起使用,来消除所有重复的记录,并只获取唯一一次记录。</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">SELECT DISTINCT name FROM COMPANY;</span><br></pre></td></tr></table></figure><h2 id="约束"><a href="#约束" class="headerlink" title="约束"></a>约束</h2><ul><li>NOT NULL 约束:确保某列不能有 NULL 值。</li><li>DEFAULT 约束:当某列没有指定值时,为该列提供默认值。</li><li>UNIQUE 约束:确保某列中的所有值是不同的。</li><li>PRIMARY Key 约束:唯一标识数据库表中的各行/记录。</li><li>CHECK 约束:CHECK 约束确保某列中的所有值满足一定条件。</li></ul><h2 id="Joins"><a href="#Joins" class="headerlink" title="Joins"></a>Joins</h2><p> Joins 子句用于结合两个或多个数据库中表的记录.</p><p>SQL 定义了三种主要类型的连接:</p><ul><li>交叉连接 - CROSS JOIN</li><li>内连接 - INNER JOIN</li><li>外连接 - OUTER JOIN (left,right,full)</li></ul><p>注意 外链接只支持 <code>left</code></p><h2 id="别名"><a href="#别名" class="headerlink" title="别名"></a>别名</h2><p>表别名</p><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">SELECT column1, column2....</span><br><span class="line">FROM table_name AS alias_name</span><br><span class="line">WHERE [condition];</span><br></pre></td></tr></table></figure><p>列别名</p><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">SELECT column_name AS alias_name</span><br><span class="line">FROM table_name</span><br><span class="line">WHERE [condition];</span><br></pre></td></tr></table></figure><h2 id="触发器(Trigger)"><a href="#触发器(Trigger)" class="headerlink" title="触发器(Trigger)"></a>触发器(Trigger)</h2><p>SQLite 的触发器是数据库的回调函数,它会自动执行/指定的数据库事件发生时调用。</p><ul><li>SQLite 的触发器(Trigger)可以指定在特定的数据库表发生 DELETE、INSERT 或 UPDATE 时触发,或在一个或多个指定表的列发生更新时触发。</li><li>SQLite 只支持 FOR EACH ROW 触发器(Trigger),没有 FOR EACH STATEMENT 触发器(Trigger)。因此,明确指定 FOR EACH ROW 是可选的。</li><li>WHEN 子句和触发器(Trigger)动作可能访问使用表单 NEW.column-name 和 OLD.column-name 的引用插入、删除或更新的行元素,其中 column-name 是从与触发器关联的表的列的名称。</li><li>如果提供 WHEN 子句,则只针对 WHEN 子句为真的指定行执行 SQL 语句。如果没有提供 WHEN 子句,则针对所有行执行 SQL 语句。</li><li>BEFORE 或 AFTER 关键字决定何时执行触发器动作,决定是在关联行的插入、修改或删除之前或者之后执行触发器动作。</li><li>当触发器相关联的表删除时,自动删除触发器(Trigger)。</li><li>要修改的表必须存在于同一数据库中,作为触发器被附加的表或视图,且必须只使用 tablename,而不是 database.tablename。</li><li>一个特殊的 SQL 函数 RAISE() 可用于触发器程序内抛出异常。</li></ul><p>创建 触发器(Trigger) 的基本语法如下:</p><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></pre></td><td class="code"><pre><span class="line">CREATE TRIGGER trigger_name [BEFORE|AFTER] event_name </span><br><span class="line">ON table_name</span><br><span class="line">BEGIN</span><br><span class="line"> -- Trigger logic goes here....</span><br><span class="line">END;</span><br></pre></td></tr></table></figure><p>在这里,event_name 可以是在所提到的表 table_name 上的 INSERT、DELETE 和 UPDATE 数据库操作。您可以在表名后选择指定 FOR EACH ROW。</p><p>以下是在 UPDATE 操作上在表的一个或多个指定列上创建触发器(Trigger)的语法:</p><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></pre></td><td class="code"><pre><span class="line">CREATE TRIGGER trigger_name [BEFORE|AFTER] UPDATE OF column_name </span><br><span class="line">ON table_name</span><br><span class="line">BEGIN</span><br><span class="line"> -- Trigger logic goes here....</span><br><span class="line">END;</span><br></pre></td></tr></table></figure><p>实例</p><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></pre></td><td class="code"><pre><span class="line">CREATE TRIGGER audit_log AFTER INSERT </span><br><span class="line">ON COMPANY</span><br><span class="line">BEGIN</span><br><span class="line"> INSERT INTO AUDIT(EMP_ID, ENTRY_DATE) VALUES (new.ID, datetime('now'));</span><br><span class="line">END;</span><br></pre></td></tr></table></figure><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">DROP TRIGGER trigger_name;</span><br></pre></td></tr></table></figure><h2 id="索引"><a href="#索引" class="headerlink" title="索引"></a>索引</h2><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">CREATE INDEX index_name</span><br><span class="line">ON table_name (column_name);</span><br></pre></td></tr></table></figure><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">CREATE UNIQUE INDEX index_name</span><br><span class="line">on table_name (column_name);</span><br></pre></td></tr></table></figure><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">CREATE INDEX index_name</span><br><span class="line">on table_name (column1, column2);</span><br></pre></td></tr></table></figure><p>虽然索引的目的在于提高数据库的性能,但这里有几个情况需要避免使用索引。使用索引时,应重新考虑下列准则:</p><ul><li>索引不应该使用在较小的表上。</li><li>索引不应该使用在有频繁的大批量的更新或插入操作的表上。</li><li>索引不应该使用在含有大量的 NULL 值的列上。</li><li>索引不应该使用在频繁操作的列上。</li></ul><h2 id="Alter-命令"><a href="#Alter-命令" class="headerlink" title="Alter 命令"></a>Alter 命令</h2><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">ALTER TABLE COMPANY RENAME TO OLD_COMPANY;</span><br></pre></td></tr></table></figure><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">ALTER TABLE OLD_COMPANY ADD COLUMN SEX char(1);</span><br></pre></td></tr></table></figure><h2 id="事务-Transaction"><a href="#事务-Transaction" class="headerlink" title="事务 (Transaction)"></a>事务 (Transaction)</h2><p>确保数据的完整性和处理数据库错误</p><p>事务(Transaction)具有以下四个标准属性,通常根据首字母缩写为 ACID:</p><ul><li>原子性(Atomicity):确保工作单位内的所有操作都成功完成,否则,事务会在出现故障时终止,之前的操作也会回滚到以前的状态。</li><li>一致性(Consistency):确保数据库在成功提交的事务上正确地改变状态。</li><li>隔离性(Isolation):使事务操作相互独立和透明。</li><li>持久性(Durability):确保已提交事务的结果或效果在系统发生故障的情况下仍然存在。</li></ul><p>使用下面的命令来控制事务:</p><ul><li>BEGIN TRANSACTION:开始事务处理。</li><li>COMMIT:保存更改,或者可以使用 END TRANSACTION 命令。</li><li>ROLLBACK:回滚所做的更改。</li></ul><h2 id="Autoincrement-自动递增"><a href="#Autoincrement-自动递增" class="headerlink" title="Autoincrement (自动递增)"></a>Autoincrement (自动递增)</h2><p>SQLite 的 AUTOINCREMENT 是一个关键字,用于表中的字段值自动递增。</p><p>关键字 AUTOINCREMENT 只能用于整型(INTEGER)字段。</p><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></pre></td><td class="code"><pre><span class="line">CREATE TABLE COMPANY(</span><br><span class="line"> ID INTEGER PRIMARY KEY AUTOINCREMENT,</span><br><span class="line"> NAME TEXT NOT NULL,</span><br><span class="line"> AGE INT NOT NULL,</span><br><span class="line"> ADDRESS CHAR(50),</span><br><span class="line"> SALARY REAL</span><br><span class="line">);</span><br></pre></td></tr></table></figure><h2 id="注入"><a href="#注入" class="headerlink" title="注入"></a>注入</h2><p>如果您的站点允许用户通过网页输入,并将输入内容插入到 SQLite 数据库中,这个时候您就面临着一个被称为 SQL 注入的安全问题</p><p>防止SQL注入</p><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">SELECT * FROM users WHERE username='{$name}'</span><br></pre></td></tr></table></figure><h2 id="内置函数"><a href="#内置函数" class="headerlink" title="内置函数"></a>内置函数</h2><ul><li>avg() 计算某列的平均值</li></ul><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">SELECT avg(salary) FROM COMPANY;</span><br></pre></td></tr></table></figure><ul><li>sum() 一个数值列计算总和</li></ul><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">SELECT sum(salary) FROM COMPANY;</span><br></pre></td></tr></table></figure><ul><li>count() 计算一个数据库表中的行数</li></ul><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">SELECT count(*) FROM COMPANY;</span><br></pre></td></tr></table></figure><ul><li>max() 选择某列的最大值</li></ul><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">SELECT max(salary) FROM COMPANY;</span><br></pre></td></tr></table></figure><ul><li>min() 选择某列的最小值</li></ul><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">SELECT min(salary) FROM COMPANY;</span><br></pre></td></tr></table></figure><ul><li>upper() 把字符串转换为大写字母</li></ul><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">SELECT upper(name) FROM t_ichat_user;</span><br></pre></td></tr></table></figure><ul><li>lower() 把字符串转换为小写字母</li></ul><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">SELECT lower(name) FROM t_ichat_user;</span><br></pre></td></tr></table></figure><ul><li>length() 返回字符串的长度</li></ul><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">SELECT name, length(name) FROM COMPANY;</span><br></pre></td></tr></table></figure><h2 id="注意"><a href="#注意" class="headerlink" title="注意"></a>注意</h2><p>SQLITE 支持</p><ul><li>重命名表</li><li>添加列</li></ul><p>不支持</p><ul><li>重命名列</li><li>删除列</li><li>添加约束</li><li>删除约束</li></ul><h2 id="数据类型"><a href="#数据类型" class="headerlink" title="数据类型"></a>数据类型</h2><p>NULL<br>INTEGER<br>REAL<br>TEXT<br>BLOB</p><h2 id="性能"><a href="#性能" class="headerlink" title="性能"></a>性能</h2><ol><li>批量更新数据使用事务 。因为每插入一条数据默认是有事务的, 显示使用事务加快速度</li><li>建立索引 (10万条数据). 优点: 加快检索速度,缺点 : 数据库物理空间增加,对增删改性能存在影响。 使用场景: 1.当某字段数据更新频率较低,查询频率较高 2. 经常同时存取多列,且每列都含有重复值可考虑建立复合</li><li>查询时返回更少的结果及更少的字段</li><li>对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。</li><li>避免 where子句中对字段进行null判断,否则将导致引擎放弃使用索引而进行全表扫描。<code>select id from t where num is null</code></li><li>避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描。</li><li>在业务密集的SQL当中尽量不采用IN操作符,用EXISTS 方案代替。</li><li>not in -> not EXISTS</li><li>避免使用*</li><li>最高效的删除重复记录 <code>DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID) FROM EMP X WHERE X.EMP_NO = E.EMP_NO)。</code></li></ol>]]></content>
<summary type="html">
<h2 id="创建表"><a href="#创建表" class="headerlink" title="创建表"></a>创建表</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><s
</summary>
<category term="sqlite" scheme="http://blog.wenbobao.cn/tags/sqlite/"/>
</entry>
<entry>
<title>cocoapods最新安装教程</title>
<link href="http://blog.wenbobao.cn/2015/03/11/cocoapods%E6%9C%80%E6%96%B0%E5%AE%89%E8%A3%85%E6%95%99%E7%A8%8B/"/>
<id>http://blog.wenbobao.cn/2015/03/11/cocoapods最新安装教程/</id>
<published>2015-03-11T02:11:29.000Z</published>
<updated>2017-12-26T16:09:18.000Z</updated>
<content type="html"><![CDATA[<p>最新安装CocoaPods命令:</p><ol><li>sudo gem update –system </li><li>gem -v</li><li>gem sources –remove <a href="https://rubygems.org/" target="_blank" rel="noopener">https://rubygems.org/</a></li><li>gem sources –add <a href="https://gems.ruby-china.org/" target="_blank" rel="noopener">https://gems.ruby-china.org/</a></li><li>gem sources –remove <a href="https://ruby.taobao.org/" target="_blank" rel="noopener">https://ruby.taobao.org/</a> </li><li>gem sources -l</li><li>sudo gem install cocoapods</li><li>pod setup</li></ol><p>CocoaPods命令:</p><ol><li>pod install –verbose –no-repo-update</li><li>pod update –verbose –no-repo-update</li></ol><h1 id="什么是CocoaPods?"><a href="#什么是CocoaPods?" class="headerlink" title="什么是CocoaPods?"></a>什么是CocoaPods?</h1><p>当你开发iOS应用时,会经常使用到很多第三方开源类库,比如JSONKit,AFNetWorking等等。可能某个类库又用到其他类库,所以要使用它,必须得另外下载其他类库,而其他类库又用到其他类库,“子子孙孙无穷尽也”,这也许是比较特殊的情况。手动一个个去下载所需类库十分麻烦。另外一种常见情况是,你项目中用到的类库有更新,你必须得重新下载新版本,重新加入到项目中,十分麻烦。</p><p>CocoaPods是一个用来帮助我们管理第三方依赖库的工具。它可以解决库与库之间的依赖关系,下载库的源代码,同时通过创建一个Xcode的workspace来将这些第三方库和我们的工程连接起来,供我们开发使用。</p><h1 id="安装ruby环境"><a href="#安装ruby环境" class="headerlink" title="安装ruby环境"></a>安装ruby环境</h1><p>在安装CocoaPods之前,首先要在本地安装好Ruby环境。幸运的事MAC自带ruby环境。<br>终端执行:<br>ruby -v<br><img src="http://7xrifx.com1.z0.glb.clouddn.com/16-10-20/39160485.jpg" alt=""></p><p>CocoaPods是以Ruby gem包的形式被安装的。<br>查看gem版本<br>gem -v<br><img src="http://7xrifx.com1.z0.glb.clouddn.com/16-10-20/74944192.jpg" alt=""></p><p>注:建议gem更新到最新版本,版本过低会影响<br>升级gem:<br>sudo gem update –system<br><img src="http://7xrifx.com1.z0.glb.clouddn.com/16-10-20/97301059.jpg" alt=""><br>升级后查看gem版本<br><img src="http://7xrifx.com1.z0.glb.clouddn.com/16-10-20/81545029.jpg" alt=""></p><h1 id="如何下载和安装CocoaPods?"><a href="#如何下载和安装CocoaPods?" class="headerlink" title="如何下载和安装CocoaPods?"></a>如何下载和安装CocoaPods?</h1><p>安装好Ruby环境后在终端执行:</p><p>sudo gem install cocoapods</p><p>在终端中敲入这个命令之后,会发现半天没有任何反应。因为cocoapods.org被墙了。</p><p>我们可以用淘宝的Ruby镜像来访问cocoapods,执行下面的命令</p><p>gem sources –remove <a href="https://rubygems.org/" target="_blank" rel="noopener">https://rubygems.org/</a></p><p>gem sources –add <a href="https://ruby.taobao.org/" target="_blank" rel="noopener">https://ruby.taobao.org/</a></p><p>为了验证你的Ruby镜像是并且仅是taobao,可以用以下命令查看:</p><p>gem sources -l</p><p>只有在终端中出现下面文字才表明你上面的命令是成功的:<br><img src="http://7xrifx.com1.z0.glb.clouddn.com/16-10-20/66595190.jpg" alt=""></p><p>这时候,你再次在终端中运行:</p><p>sudo gem install cocoapods</p><p>等上十几秒钟,CocoaPods就可以安装完毕。</p><p>2016年10月更新:<br> 由于Ruby TaoBao不在更新维护 , RubyGems镜像的管理工作以后将交由 Ruby China 负责,我们需要将RubyGems source 切换到 Ruby China。</p>]]></content>
<summary type="html">
<p>最新安装CocoaPods命令:</p>
<ol>
<li>sudo gem update –system </li>
<li>gem -v</li>
<li>gem sources –remove <a href="https://rubygems.org/" targe
</summary>
<category term="cocoapods" scheme="http://blog.wenbobao.cn/tags/cocoapods/"/>
</entry>
<entry>
<title>记录下Xcode好用的插件</title>
<link href="http://blog.wenbobao.cn/2015/02/07/%E8%AE%B0%E5%BD%95%E4%B8%8BXcode%E5%A5%BD%E7%94%A8%E7%9A%84%E6%8F%92%E4%BB%B6/"/>
<id>http://blog.wenbobao.cn/2015/02/07/记录下Xcode好用的插件/</id>
<published>2015-02-07T08:58:30.000Z</published>
<updated>2017-12-26T16:09:25.000Z</updated>
<content type="html"><![CDATA[<ol><li><p>Auto-Importer-for-Xcode-master<br> github地址: <a href="https://github.com/lucholaf/Auto-Importer-for-Xcode" target="_blank" rel="noopener">https://github.com/lucholaf/Auto-Importer-for-Xcode</a></p></li><li><p>ClangFormat-Xcode-master<br> github地址: <a href="https://github.com/travisjeffery/ClangFormat-Xcode" target="_blank" rel="noopener">https://github.com/travisjeffery/ClangFormat-Xcode</a></p></li><li><p>ColorSense-for-Xcode-master<br> github地址: <a href="https://github.com/omz/ColorSense-for-Xcode" target="_blank" rel="noopener">https://github.com/omz/ColorSense-for-Xcode</a></p></li><li><p>deriveddata-exterminator-master<br> github地址: <a href="https://github.com/kattrali/deriveddata-exterminator" target="_blank" rel="noopener">https://github.com/kattrali/deriveddata-exterminator</a></p></li><li><p>KSImageNamed-Xcode-master<br> github地址<a href="https://github.com/ksuther/KSImageNamed-Xcode" target="_blank" rel="noopener">https://github.com/ksuther/KSImageNamed-Xcode</a></p></li><li><p>ObjectGraph-Xcode-master </p><p> github地址<a href="https://github.com/vampirewalk/ObjectGraph-Xcode" target="_blank" rel="noopener">https://github.com/vampirewalk/ObjectGraph-Xcode</a></p></li><li><p>RSImageOptimPlugin-master</p><p> github地址<a href="https://github.com/yeahdongcn/RSImageOptimPlugin" target="_blank" rel="noopener">https://github.com/yeahdongcn/RSImageOptimPlugin</a></p></li><li><p>SCXcodeSwitchExpander-master </p><p> github地址<a href="https://github.com/stefanceriu/SCXcodeSwitchExpander" target="_blank" rel="noopener">https://github.com/stefanceriu/SCXcodeSwitchExpander</a></p></li><li><p>VVDocumenter-Xcode-master </p><p> github地址<a href="https://github.com/onevcat/VVDocumenter-Xcode" target="_blank" rel="noopener">https://github.com/onevcat/VVDocumenter-Xcode</a></p></li><li><p>xcodeTheme-master </p><p>github地址<a href="https://github.com/laughmaker/xcodeTheme" target="_blank" rel="noopener">https://github.com/laughmaker/xcodeTheme</a></p></li><li><p>XToDo-master </p><p>github地址<a href="https://github.com/trawor/XToDo" target="_blank" rel="noopener">https://github.com/trawor/XToDo</a></p></li><li><p>ZLCheckFilePlugin-Xcode-master</p><p>github地址<a href="https://github.com/MakeZL/ZLCheckFilePlugin-Xcode" target="_blank" rel="noopener">https://github.com/MakeZL/ZLCheckFilePlugin-Xcode</a></p></li><li><p>ZLGotoSandboxPlugin-master </p><p>github地址<a href="https://github.com/MakeZL/ZLGotoSandboxPlugin" target="_blank" rel="noopener">https://github.com/MakeZL/ZLGotoSandboxPlugin</a></p><hr></li></ol><p>网络不好的童鞋可以去下面这个地址下载:</p><p><a href="http://pan.baidu.com/s/1dDrjcg5" target="_blank" rel="noopener">http://pan.baidu.com/s/1dDrjcg5</a></p>]]></content>
<summary type="html">
<ol>
<li><p>Auto-Importer-for-Xcode-master<br> github地址: <a href="https://github.com/lucholaf/Auto-Importer-for-Xcode" target="_blank" rel="
</summary>
<category term="Xcode插件" scheme="http://blog.wenbobao.cn/tags/Xcode%E6%8F%92%E4%BB%B6/"/>
</entry>
<entry>
<title>Xcode6为什么删掉pch文件</title>
<link href="http://blog.wenbobao.cn/2014/09/15/Xcode6%E4%B8%BA%E4%BB%80%E4%B9%88%E5%88%A0%E6%8E%89pch/"/>
<id>http://blog.wenbobao.cn/2014/09/15/Xcode6为什么删掉pch/</id>
<published>2014-09-15T07:00:21.000Z</published>
<updated>2017-12-26T14:07:26.000Z</updated>
<content type="html"><![CDATA[<h2 id="为什么xcode6没有自动创建pch文件"><a href="#为什么xcode6没有自动创建pch文件" class="headerlink" title="为什么xcode6没有自动创建pch文件"></a>为什么xcode6没有自动创建pch文件</h2><p>从xcode6之后,创建新项目,没有自动创建pch文件。stackoverflow上搜索了一下:<br><a href="http://stackoverflow.com/questions/24158648/why-isnt-projectname-prefix-pch-created-automatically-in-xcode-6" target="_blank" rel="noopener">Why isn’t ProjectName-Prefix.pch created automatically in Xcode 6?</a></p><p>概括如下:</p><ol><li>pch会增加编译时间</li><li>pch放的是全局都使用的code, 大量代码放入pch中会影响代码重用。</li><li>把头文件引入到需要它的类中。</li></ol><h2 id="怎么添加pch"><a href="#怎么添加pch" class="headerlink" title="怎么添加pch"></a>怎么添加pch</h2><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></pre></td><td class="code"><pre><span class="line">1. xcode - > File - > new PCH文件 </span><br><span class="line">2. 点击工程名称 — > Build Settings — > Prefix Header — > 加入 $(SRCROOT)/$(PROJECT)/PrefixHeader.pch</span><br><span class="line">3. Build Settings — > Precompile Prefix Header — > 设置为 YES</span><br><span class="line">4. clean & build project</span><br></pre></td></tr></table></figure><p>最后需要在pch文件中加入</p><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></pre></td><td class="code"><pre><span class="line">#ifdef __OBJC__</span><br><span class="line"> #import <UIKit/UIKit.h></span><br><span class="line"> #import <Foundation/Foundation.h></span><br><span class="line">#endif</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="为什么xcode6没有自动创建pch文件"><a href="#为什么xcode6没有自动创建pch文件" class="headerlink" title="为什么xcode6没有自动创建pch文件"></a>为什么xcode6没有自动创建pch文件</h2><
</summary>
<category term="Xcode" scheme="http://blog.wenbobao.cn/tags/Xcode/"/>
</entry>
<entry>
<title>iOS给图片添加水印</title>
<link href="http://blog.wenbobao.cn/2014/06/11/iOS%E7%BB%99%E5%9B%BE%E7%89%87%E6%B7%BB%E5%8A%A0%E6%B0%B4%E5%8D%B0/"/>
<id>http://blog.wenbobao.cn/2014/06/11/iOS给图片添加水印/</id>
<published>2014-06-11T02:11:29.000Z</published>
<updated>2017-12-26T16:06:42.000Z</updated>
<content type="html"><![CDATA[<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></pre></td><td class="code"><pre><span class="line">+ (instancetype)waterMarkWithImageName:(NSString *)backgroundImage</span><br><span class="line">andMarkImageName:(NSString *)markName</span><br><span class="line">{</span><br><span class="line"></span><br><span class="line"> UIImage *bgImage = [UIImage imageNamed:backgroundImage];</span><br><span class="line"></span><br><span class="line"> UIGraphicsBeginImageContextWithOptions(bgImage.size, NO, 0.0);</span><br><span class="line"> [bgImage drawInRect:CGRectMake(0, 0, bgImage.size.width, bgImage.size.height)];</span><br><span class="line"></span><br><span class="line"> UIImage *waterImage = [UIImage imageNamed:markName];</span><br><span class="line"> CGFloat scale = 0.3;</span><br><span class="line"> CGFloat margin = 5;</span><br><span class="line"> CGFloat waterW = waterImage.size.width * scale;</span><br><span class="line"> CGFloat waterH = waterImage.size.height * scale;</span><br><span class="line"> CGFloat waterX = bgImage.size.width - waterW - margin;</span><br><span class="line"> CGFloat waterY = bgImage.size.height - waterH - margin;</span><br><span class="line"></span><br><span class="line"> [waterImage drawInRect:CGRectMake(waterX, waterY, waterW, waterH)];</span><br><span class="line"></span><br><span class="line"> UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();</span><br><span class="line"> UIGraphicsEndImageContext();</span><br><span class="line"></span><br><span class="line"> return newImage;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class
</summary>
</entry>
<entry>
<title>iOS获取当前网络的IP地址</title>
<link href="http://blog.wenbobao.cn/2014/04/10/iOS%E8%8E%B7%E5%8F%96%E5%BD%93%E5%89%8D%E7%BD%91%E7%BB%9C%E7%9A%84IP%E5%9C%B0%E5%9D%80/"/>
<id>http://blog.wenbobao.cn/2014/04/10/iOS获取当前网络的IP地址/</id>
<published>2014-04-10T03:41:11.000Z</published>
<updated>2017-12-26T14:52:38.000Z</updated>
<content type="html"><![CDATA[<p>Objective code :<br>、、、</p><ul><li>(NSString <em>)getIPAddress<br>{<br>NSString </em>address = @”error”;<br>struct ifaddrs <em>interfaces = NULL;<br>struct ifaddrs </em>temp_addr = NULL;<br>int success = 0;</li></ul><p>// retrieve the current interfaces - returns 0 on success<br>success = getifaddrs(&interfaces);<br>if (success == 0)<br>{<br>// Loop through linked list of interfaces<br>temp_addr = interfaces;<br>while(temp_addr != NULL)<br>{<br>if(temp_addr->ifa_addr->sa_family == AF_INET)<br>{<br>// Check if interface is en0 which is the wifi connection on the iPhone<br>if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@”en0”])<br>{<br>// Get NSString from C String<br>address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];<br>}<br>}<br>temp_addr = temp_addr->ifa_next;<br>}<br>}<br>// Free memory<br>freeifaddrs(interfaces);<br>return address;<br>} </p><p>、、、</p>]]></content>
<summary type="html">
<p>Objective code :<br>、、、</p>
<ul>
<li>(NSString <em>)getIPAddress<br>{<br>NSString </em>address = @”error”;<br>struct ifaddrs <em>interfac
</summary>
<category term="IP Address" scheme="http://blog.wenbobao.cn/tags/IP-Address/"/>
</entry>
<entry>
<title>Markdown 语法</title>
<link href="http://blog.wenbobao.cn/2014/03/09/Markdown%E8%AF%AD%E6%B3%95/"/>
<id>http://blog.wenbobao.cn/2014/03/09/Markdown语法/</id>
<published>2014-03-09T03:41:11.000Z</published>
<updated>2017-12-26T14:07:26.000Z</updated>
<content type="html"><![CDATA[<h2 id="Markdown-优点"><a href="#Markdown-优点" class="headerlink" title="Markdown 优点:"></a>Markdown 优点:</h2><ul><li>纯文本,所以兼容性极强,可以用所有文本编辑器打开。</li><li>让你专注于文字而不是排版。</li><li>格式转换方便,Markdown 的文本你可以轻松转换为 html、电子书等。</li><li>Markdown 的标记语法有极好的可读性。</li></ul><h2 id="标题"><a href="#标题" class="headerlink" title="标题"></a>标题</h2><p>这是最为常用的格式,在平时常用的的文本编辑器中大多是这样实现的:输入文本、选中文本、设置标题格式。 而在 Markdown 中,你只需要在文本前面加上 # 即可,同理、你还可以增加二级标题、三级标题、四级标题、五级标题和六级标题,总共六级,只需要增加 # 即可,标题字号相应降低。例如:<br><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></pre></td><td class="code"><pre><span class="line"># 一级标题 </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">###### 六级标题</span><br></pre></td></tr></table></figure></p><p>注:# 和「一级标题」之间建议保留一个字符的空格,这是最标准的 Markdown 写法。</p><h2 id="列表"><a href="#列表" class="headerlink" title="列表"></a>列表</h2><p>列表格式也很常用,在 Markdown 中,你只需要在文字前面加上 - 就可以了,例如:<br><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">- 文本1</span><br><span class="line">- 文本2</span><br><span class="line">- 文本3</span><br></pre></td></tr></table></figure></p><p>如果你希望有序列表,也可以在文字前面加上 1. 2. 3. 就可以了,例如:<br><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">1. 文本1</span><br><span class="line">2. 文本2</span><br><span class="line">3. 文本3</span><br></pre></td></tr></table></figure></p><p>显示效果如下 :</p><ol><li>文本1</li><li>文本2</li><li>文本3</li></ol><p>注:- 和 1. 和文本之间要保留一个字符的空格。</p><h2 id="链接和图片"><a href="#链接和图片" class="headerlink" title="链接和图片"></a>链接和图片</h2><p>在 Markdown 中,插入链接不需要其他按钮,你只需要使用 [显示文本](链接地址) 这样的语法即可,例如:<br><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">[简书](http://jianshu.io)</span><br></pre></td></tr></table></figure></p><p>在 Markdown 中,插入图片不需要其他按钮,你只需要使用 ![](图片链接地址) 这样的语法即可,例如:<br><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">![](http://ww4.sinaimg.cn/bmiddle/aa397b7fjw1dzplsgpdw5j.jpg)</span><br></pre></td></tr></table></figure></p><p>注:插入图片的语法和链接的语法很像,只是前面多了一个 !。</p><h2 id="引用"><a href="#引用" class="headerlink" title="引用"></a>引用</h2><p>在我们写作的时候经常需要引用他人的文字,这个时候引用这个格式就很有必要了,在 Markdown 中,你只需要在你希望引用的文字前面加上 > 就好了,例如:<br><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">> 一盏灯, 一片昏黄; 一简书, 一杯淡茶。 守着那一份淡定, 品读属于自己的寂寞。 保持淡定, 才能欣赏到最美丽的风景! 保持淡定, 人生从此不再寂寞。</span><br></pre></td></tr></table></figure></p><p>注:> 和文本之间要保留一个字符的空格。</p><p>最终显示的就是:</p><blockquote><p>一盏灯, 一片昏黄; 一简书, 一杯淡茶。 守着那一份淡定, 品读属于自己的寂寞。 保持淡定, 才能欣赏到最美丽的风景! 保持淡定, 人生从此不再寂寞。</p></blockquote><h2 id="粗体和斜体"><a href="#粗体和斜体" class="headerlink" title="粗体和斜体"></a>粗体和斜体</h2><p>Markdown 的粗体和斜体也非常简单,用两个 <em> 包含一段文本就是粗体的语法,用一个 </em> 包含一段文本就是斜体的语法。例如:<br><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">*一盏灯*, 一片昏黄;**一简书**, 一杯淡茶。 守着那一份淡定, 品读属于自己的寂寞。 保持淡定, 才能欣赏到最美丽的风景! 保持淡定, 人生从此不再寂寞。</span><br></pre></td></tr></table></figure></p><p>最终显示的就是下文,其中「一盏灯」是斜体,「一简书」是粗体:</p><p><em>一盏灯</em>, 一片昏黄;<strong>一简书</strong>, 一杯淡茶。 守着那一份淡定, 品读属于自己的寂寞。 保持淡定, 才能欣赏到最美丽的风景! 保持淡定, 人生从此不再寂寞。</p><h2 id="表格"><a href="#表格" class="headerlink" title="表格"></a>表格</h2><p>相关代码:<br><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></pre></td><td class="code"><pre><span class="line">| Tables | Are | Cool | </span><br><span class="line">| ------------- |:-------------:| -----:| </span><br><span class="line">| col 3 is | right-aligned | $1600 | </span><br><span class="line">| col 2 is | centered | $12 | </span><br><span class="line">| zebra stripes | are neat | $1 |</span><br></pre></td></tr></table></figure></p><p>显示效果:</p><table><thead><tr><th>Tables</th><th style="text-align:center">Are</th><th style="text-align:right">Cool</th></tr></thead><tbody><tr><td>col 3 is</td><td style="text-align:center">right-aligned</td><td style="text-align:right">$1600</td></tr><tr><td>col 2 is</td><td style="text-align:center">centered</td><td style="text-align:right">$12</td></tr><tr><td>zebra stripes</td><td style="text-align:center">are neat</td><td style="text-align:right">$1</td></tr></tbody></table><p>相关代码:<br><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></pre></td><td class="code"><pre><span class="line">dog | bird | cat</span><br><span class="line">----|------|----</span><br><span class="line">foo | foo | foo</span><br><span class="line">bar | bar | bar</span><br><span class="line">baz | baz | baz</span><br></pre></td></tr></table></figure></p><p>显示效果:</p><table><thead><tr><th>dog</th><th>bird</th><th>cat</th></tr></thead><tbody><tr><td>foo</td><td>foo</td><td>foo</td></tr><tr><td>bar</td><td>bar</td><td>bar</td></tr><tr><td>baz</td><td>baz</td><td>baz</td></tr></tbody></table><h2 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h2><p>以上几种格式是比较常用的格式,所以我们针对这些语法做了比较详细的说明。除这些之外,Markdown 还有其他语法,如想了解和学习更多,可以参考这篇 <a href="http://wowubuntu.com/markdown/" target="_blank" rel="noopener">Markdown 语法说明</a></p><p>强烈建议您现在就立马用 Markdown 写一篇文章吧,体会一下 Markdown 的优雅之处!</p>]]></content>
<summary type="html">
<h2 id="Markdown-优点"><a href="#Markdown-优点" class="headerlink" title="Markdown 优点:"></a>Markdown 优点:</h2><ul>
<li>纯文本,所以兼容性极强,可以用所有文本编辑器打开。<
</summary>
<category term="Markdown" scheme="http://blog.wenbobao.cn/tags/Markdown/"/>
</entry>
</feed>