-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
536 lines (367 loc) · 27.6 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge" >
<title>GuobiXie</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="description" content="Yesterday You Said Tomorrow">
<meta property="og:type" content="website">
<meta property="og:title" content="GuobiXie">
<meta property="og:url" content="http://hiXgb.github.io/index.html">
<meta property="og:site_name" content="GuobiXie">
<meta property="og:description" content="Yesterday You Said Tomorrow">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="GuobiXie">
<meta name="twitter:description" content="Yesterday You Said Tomorrow">
<link rel="icon" href="/favicon.png">
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<div id="container">
<div class="left-col">
<div class="overlay"></div>
<div class="intrude-less">
<header id="header" class="inner">
<a href="/" class="profilepic">
<img src="http://ww1.sinaimg.cn/mw690/bcfa9841jw8etywtmgzmqj20ku0kumye.jpg" class="js-avatar" style="width: 100%;height: 100%;opacity: 1;">
</a>
<hgroup>
<h1 class="header-author"><a href="/">Billy</a></h1>
</hgroup>
<p class="header-subtitle">Yesterday You Said Tomorrow</p>
<div class="switch-btn">
<div class="icon">
<div class="icon-ctn">
<div class="icon-wrap icon-house" data-idx="0">
<div class="birdhouse"></div>
<div class="birdhouse_holes"></div>
</div>
<div class="icon-wrap icon-ribbon hide" data-idx="1">
<div class="ribbon"></div>
</div>
<div class="icon-wrap icon-me hide" data-idx="3">
<div class="user"></div>
<div class="shoulder"></div>
</div>
</div>
</div>
<div class="tips-box hide">
<div class="tips-arrow"></div>
<ul class="tips-inner">
<li>菜单</li>
<li>标签</li>
<li>关于我</li>
</ul>
</div>
</div>
<div class="switch-area">
<div class="switch-wrap">
<section class="switch-part switch-part1">
<nav class="header-menu">
<ul>
<li><a href="/">主页</a></li>
<li><a href="/archives">所有文章</a></li>
</ul>
</nav>
<nav class="header-nav">
<div class="social">
<a class="github" target="_blank" href="https://github.com/hiXgb" title="github">github</a>
<a class="zhihu" target="_blank" href="https://www.zhihu.com/people/xie-guo-bi" title="zhihu">zhihu</a>
</div>
</nav>
</section>
<section class="switch-part switch-part2">
<div class="widget tagcloud" id="js-tagcloud">
</div>
</section>
<section class="switch-part switch-part3">
<div id="js-aboutme">Hi,我是谢国碧,iOS程序猿一枚,热爱生活,喜爱一切美好事物;热爱技术,包容接受新技术。</div>
</section>
</div>
</div>
</header>
</div>
</div>
<div class="mid-col">
<nav id="mobile-nav">
<div class="overlay">
<div class="slider-trigger"></div>
<h1 class="header-author js-mobile-header hide">Billy</h1>
</div>
<div class="intrude-less">
<header id="header" class="inner">
<div class="profilepic">
<img src="http://ww1.sinaimg.cn/mw690/bcfa9841jw8etywtmgzmqj20ku0kumye.jpg" class="js-avatar" style="width: 100%;height: 100%;opacity: 1;">
</div>
<hgroup>
<h1 class="header-author">Billy</h1>
</hgroup>
<p class="header-subtitle">Yesterday You Said Tomorrow</p>
<nav class="header-menu">
<ul>
<li><a href="/">主页</a></li>
<li><a href="/archives">所有文章</a></li>
<div class="clearfix"></div>
</ul>
</nav>
<nav class="header-nav">
<div class="social">
<a class="github" target="_blank" href="https://github.com/hiXgb" title="github">github</a>
<a class="zhihu" target="_blank" href="https://www.zhihu.com/people/xie-guo-bi" title="zhihu">zhihu</a>
</div>
</nav>
</header>
</div>
</nav>
<div class="body-wrap">
<article id="post-iOS沙盒目录" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2016/03/06/iOS沙盒目录/" class="article-date">
<time datetime="2016-03-06T15:44:36.000Z" itemprop="datePublished">2016-03-06</time>
</a>
</div>
<div class="article-inner">
<input type="hidden" class="isFancy" />
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2016/03/06/iOS沙盒目录/">iOS沙盒目录</a>
</h1>
<div style="font-size:14px;margin-top:15px">
<span id="busuanzi_value_page_pv"></span>次访问
</div>
</header>
<div class="article-entry" itemprop="articleBody">
<p>iOS沙盒目录</p>
<p> iOS应用程序只能在为该改程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒。苹果官方文档中有如下一张图介绍沙盒目录:</p>
<p><img src="http://ww4.sinaimg.cn/mw690/bcfa9841gw1f1nig1mrccj20la0n6gnm.jpg" alt=""></p>
<p>官方文档对于沙盒中常用的目录做了说明,有如下几个常用目录:</p>
<ol>
<li>AppName.app:该目录包含了应用程序本身的数据,包括资源文件和可执行文件等。整个目录是只读的,并且不会被iTunes同步。可通过<code>NSString *bundlePath = [[NSBundle mainBundle] bundlePath];</code>获取到路径地址。</li>
<li><p>Documents/:我们可以将应用程序的数据文件保存在该目录下。不过这些数据类型仅限于不可再生的数据,可再生的数据文件应该存放在Library/Cache目录下。该目录会被iTunes同步,可通过<code>NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;</code>获取到路径地址。</p>
<ul>
<li>Documents/Inbox:外部应用程序需要访问的文件保存在该目录下,例如系统的邮件App要使用到当前应用程序的附件资源就存放在这个目录。沙盒机制是不允许外部程序访问沙盒中的文件,因此苹果的解决方案是将文件拷贝一份到应用的Documents/Inbox目录下。该目录只读,不可修改,会被iTunes同步。</li>
</ul>
</li>
<li><p>Library/:存放默认设置或其它状态信息。除了Caches子目录外其他目录都会被iTunes同步。</p>
<ul>
<li>Library/Preferences:NSUserDefaults写的设置数据都会保存到该目录下的一个plist文件中,会被iTunes同步。</li>
<li>Library/Caches: iTunes不会同步此文件夹,适合存储体积大,不需要备份的非重要数据。可通过<code>NSString *cachesPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;</code>获取到路径地址。</li>
</ul>
</li>
<li><p>tmp/:各种临时文件,保存应用再次启动时不需要的文件。而且,当应用不再需要这些文件时应该主动将其删除,因为该目录下的东西随时有可能被系统清理掉,目前已知的一种可能清理的原因是系统磁盘存储空间不足的时候。可通过<code>NSString *tmpPath = NSTemporaryDirectory();</code>获取到路径地址。</p>
</li>
</ol>
<p>写了一个小工具类用来获取这些路径地址:<a href="https://github.com/hiXgb/BBDocumentPathUtil.git" target="_blank" rel="external">https://github.com/hiXgb/BBDocumentPathUtil.git</a></p>
<p>参考文档:<a href="https://developer.apple.com/library/mac/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html" target="_blank" rel="external">https://developer.apple.com/library/mac/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html</a></p>
</div>
<div class="article-info article-info-index">
<div class="clearfix"></div>
</div>
</div>
</article>
<article id="post-iOS事件传递和响应机制" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2016/03/06/iOS事件传递和响应机制/" class="article-date">
<time datetime="2016-03-06T05:12:57.000Z" itemprop="datePublished">2016-03-06</time>
</a>
</div>
<div class="article-inner">
<input type="hidden" class="isFancy" />
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2016/03/06/iOS事件传递和响应机制/">iOS事件传递和响应机制</a>
</h1>
<div style="font-size:14px;margin-top:15px">
<span id="busuanzi_value_page_pv"></span>次访问
</div>
</header>
<div class="article-entry" itemprop="articleBody">
<p>本文主要参考了 <a href="http://www.jianshu.com/users/93131dfba96a/latest_articles" target="_blank" rel="external">VV木公子(简书作者)</a>的 <a href="http://www.jianshu.com/p/2e074db792ba" target="_blank" rel="external">史上最详细的iOS之事件的传递和响应机制</a><br>我按照自己的理解做了排版和一些表述的修改。</p>
<p>在开发过程中我们经常会遇到一些事件响应优先级的问题,通过搜索知道了hitTest,再根据hitTest去搜索一些类似问题,问题最终是解决了,但是我们得知道为什么是这么解决的。以下内容就是详细说明iOS的事件传递和响应机制。</p>
<p>(一)iOS中的事件</p>
<p>iOS的事件分为3大类型:</p>
<ol>
<li>触摸事件</li>
<li>加速计事件</li>
<li>远程控制事件</li>
</ol>
<p>本篇只讨论触摸事件</p>
<p>1.1 响应者对象(UIResponder)</p>
<p>在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接受并处理事件,我们称之为“响应者对象”。以下都是继承自UIResponder的,所以都能接收并处理事件。</p>
<ul>
<li>UIApplication</li>
<li>UIViewController</li>
<li>UIView</li>
</ul>
<p>UIViewController可以通过在.m中覆写相关方法来处理事件,例如touchesBegan、touchesMoved等;UIView则必须通过自定义子类来处理。</p>
<p>(二)iOS中事件的产生和传递</p>
<p>2.1 事件的产生</p>
<ol>
<li>发生触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件队列中。为什么是队列而不是栈?因为队列的特点是先进先出,先产生的事件先处理才符合常理,所以把事件添加到队列。</li>
<li>UIApplication会从事件队列中取出最前面的事件,并将事件分发下去以便处理,通常先发送事件给应用程序的主窗口(keyWindow)。</li>
<li>主窗口(keyWindow)会在视图层次结构中找到一个最合适的视图来处理触摸事件,寻找最合适的视图的关键就是hitTest:withEvent:方法。</li>
</ol>
<p>2.2 事件的传递</p>
<p>事件的传递是自上到下的顺序,即UIApplication->window->处理事件最合适的view。</p>
<ol>
<li>首先判断主窗口(keyWindow)自己是否能接受触摸事件</li>
<li>判断触摸点是否在自己身上</li>
<li>子控件数组中从后往前遍历子控件,重复前面的两个步骤(所谓从后往前遍历子控件,就是首先查找子控件数组中最后一个元素,然后执行1、2步骤)</li>
<li>通过前3步寻找到了fitView,那么会把这个事件交给这个fitView,再遍历这个fitView的子控件,直至没有更合适的view为止。</li>
<li>如果没有符合条件的子控件,那么就认为自己最合适处理这个事件,也就是自己是最合适的view。</li>
</ol>
<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><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></pre></td><td class="code"><pre><span class="line">- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{</span><br><span class="line"> // 1.判断下窗口能否接收事件</span><br><span class="line"> if (self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01) return nil;</span><br><span class="line"> // 2.判断下点在不在窗口上</span><br><span class="line"> // 不在窗口上</span><br><span class="line"> if ([self pointInside:point withEvent:event] == NO) return nil;</span><br><span class="line"> // 3.从后往前遍历子控件数组</span><br><span class="line"> int count = (int)self.subviews.count;</span><br><span class="line"> for (int i = count - 1; i >= 0; i--) {</span><br><span class="line"> // 获取子控件</span><br><span class="line"> UIView *childView = self.subviews[i];</span><br><span class="line"> // 坐标系的转换,把窗口上的点转换为子控件上的点</span><br><span class="line"> // 把自己控件上的点转换成子控件上的点</span><br><span class="line"> CGPoint childP = [self convertPoint:point toView:childView];</span><br><span class="line"> UIView *fitView = [childView hitTest:childP withEvent:event];</span><br><span class="line"> if (fitView) {</span><br><span class="line"> // 如果能找到最合适的view</span><br><span class="line"> return fitView;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> // 4.没有找到更合适的view,也就是没有比自己更合适的view</span><br><span class="line"> return self;</span><br><span class="line">}</span><br><span class="line">// 作用:判断下传入过来的点在不在方法调用者的坐标系上</span><br><span class="line">// point:是方法调用者坐标系上的点</span><br><span class="line">//- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event</span><br><span class="line">//{</span><br><span class="line">// return NO;</span><br><span class="line">//}</span><br></pre></td></tr></table></figure>
<p>知道了hitTest的作用,我们可以通过覆写它来达到干涉事件的传递。例如whiteView上有两个view,一个redView,一个greenView,redView先添加到父视图上,系统默认将事件传递给后添加的view也就是greenView上,如果我们想让redView响应事件可通过覆写whiteView的hitTest方法指定返回redView,再在redView的touch处理方法中执行就达到了事件拦截的目的。</p>
<p>UIView不能接收触摸事件的三种情况:</p>
<ol>
<li>不允许交互:userInteractionEnabled = NO</li>
<li>隐藏:如果把父控件隐藏,那么子控件也会隐藏,隐藏的控件不能接受事件</li>
<li><p>透明度:如果设置一个控件的透明度<0.01,会直接影响子控件的透明度。alpha:0.0~0.01为透明。</p>
<pre><code>注意:默认UIImageView不能接受触摸事件,因为不允许交互,即userInteractionEnabled = NO,所以如果希望UIImageView可以交互,需要userInteractionEnabled = YES。
</code></pre></li>
</ol>
<p>(三)iOS中事件的响应</p>
<p>在iOS程序中无论是最后面的UIWindow还是最前面的某个按钮,它们的摆放是有前后关系的,一个控件可以放到另一个控件上面或下面,那么用户点击某个控件时是触发上面的控件还是下面的控件呢,这种先后关系构成一个链条就叫“响应者链”。也可以说,响应者链是由多个响应者对象连接起来的链条。在iOS中响应者链的关系可以用下图表示:<br><img src="http://ww2.sinaimg.cn/mw690/bcfa9841gw1f1n20vp32fj20gr0933zm.jpg" alt=""></p>
<p>3.1 响应者链的事件传递过程:</p>
<ol>
<li>如果当前view是控制器的view,那么控制器就是上一个响应者,事件就传递给控制器;如果当前view不是控制器的view,那么父视图就是当前view的上一个响应者,事件就传递给它的父视图。</li>
<li>在视图层次结构的最顶级视图,如果也不能处理收到的事件或消息,则其将事件或消息传递给window对象进行处理。</li>
<li>如果window对象也不处理,则其将事件或消息传递给UIApplication对象。</li>
<li>如果UIApplication也不能处理该事件或消息,则将其丢弃。</li>
</ol>
<p>(四)iOS事件传递和响应总结:</p>
<ol>
<li>当一个事件发生后,事件会从父控件传给子控件,也就是说由UIApplication -> UIWindow -> UIView -> fit view,以上就是事件的传递,也就是寻找最合适的view的过程。</li>
<li>接下来是事件的响应。首先看fit view能否处理这个事件,如果不能则会将事件传递给其上级视图(fit view的superView);如果上级视图仍然无法处理则会继续往上传递;一直传递到视图控制器view controller,首先判断视图控制器的根视图view是否能处理此事件;如果不能则接着判断该视图控制器能否处理此事件,如果还是不能则继续向上传 递;(对于第二个图视图控制器本身还在另一个视图控制器中,则继续交给父视图控制器的根视图,如果根视图不能处理则交给父视图控制器处理);一直到window,如果window还是不能处理此事件则继续交给application处理,如果最后application还是不能处理此事件则将其丢弃。</li>
<li>在事件的响应中,如果某个控件实现了touches…方法,则这个事件将由该控件来接受,如果调用了[super touches….];就会将事件顺着响应者链条往上传递,传递给上一个响应者;接着就会调用上一个响应者的touches….方法。</li>
</ol>
</div>
<div class="article-info article-info-index">
<div class="clearfix"></div>
</div>
</div>
</article>
<article id="post-2016-03-04-iosduo-xian-cheng" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2016/03/04/2016-03-04-iosduo-xian-cheng/" class="article-date">
<time datetime="2016-03-04T07:36:48.000Z" itemprop="datePublished">2016-03-04</time>
</a>
</div>
<div class="article-inner">
<input type="hidden" class="isFancy" />
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2016/03/04/2016-03-04-iosduo-xian-cheng/">iOS多线程</a>
</h1>
<div style="font-size:14px;margin-top:15px">
<span id="busuanzi_value_page_pv"></span>次访问
</div>
</header>
<div class="article-entry" itemprop="articleBody">
<h3 id="NSThread"><a href="#NSThread" class="headerlink" title="NSThread"></a>NSThread</h3><p>基于线程</p>
<h3 id="GCD"><a href="#GCD" class="headerlink" title="GCD"></a>GCD</h3><p>基于task</p>
<ul>
<li><p>同步异步</p>
<ul>
<li>dispatch_sync在当前线程同步执行,当前线程被阻塞,后续的代码片段需要等sync任务执行完返回后才被执行,即使加入到并行队列也不开新线程。</li>
<li>dispatch_async不阻塞当前线程,在当前线程直接返回,后续代码片段接着执行,会开新线程。</li>
</ul>
</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><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"> dispatch_queue_t申明时要注意是否在ARC环境下使用,可用如下方式使用</span><br><span class="line"> </span><br><span class="line"> #if OS_OBJECT_USE_OBJC</span><br><span class="line">@property (nonatomic, strong) dispatch_queue_t queue;</span><br><span class="line">#else</span><br><span class="line">@property (nonatomic, assign) dispatch_queue_t queue;</span><br><span class="line">#endif</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">dispatch_queue_t concurrentQueue = dispatch_queue_create("com.company.concurrentQueue", DISPATCH_QUEUE_CONCURRENT);</span><br></pre></td></tr></table></figure>
<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">dispatch_queue_t serialQueue = dispatch_queue_create("com.company.serialQueue", DISPATCH_QUEUE_SERIAL);</span><br></pre></td></tr></table></figure>
<ul>
<li>串行队列一次只能执行一个任务,根据入队的顺序执行任务,一个任务执行完下一个任务开始的时间是不确定的 </li>
<li>并行队列可以同时执行多个任务,系统会维护一个线程池来保证并行队列的执行。系统只保证根据入队的顺序开始执行,因此task的开始执行时间是顺序的,但是每个task的时长不确定,有可能会出现多个task在同一时间需要同时执行,此时就需要另开线程来执行了。线程池会根据当前任务量自行安排线程的数量,以确保任务尽快执行。(因为是系统维护,有可能出现某个时间段线程数过多的问题)</li>
</ul>
</li>
</ul>
<ul>
<li><p>使用GCD常见死锁 </p>
<p> 在同一个串行队列中又用dispatch_sync的方式添加了任务</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></pre></td><td class="code"><pre><span class="line"> //serialQueue是同一个串行队列</span><br><span class="line"> dispatch_async(serialQueue, ^{</span><br><span class="line"> //some tasks</span><br><span class="line"></span><br><span class="line"> dispatch_sync(serialQueue, ^{ //发生死锁</span><br><span class="line"></span><br><span class="line"> });</span><br><span class="line">});</span><br></pre></td></tr></table></figure>
<p> 在主线程dispatch_sync就是上述的常见场景</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">//在主线程执行</span><br><span class="line">dispatch_sync(mainQueue, ^{ //发生死锁</span><br><span class="line"></span><br><span class="line"> });</span><br></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p>部分api记录</p>
<ul>
<li>dispatch_apply,在指定的queue循环执行task</li>
<li><p>dispatch_barrier,在并行队列中,有的时候我们需要让某个任务单独执行,也就是他执行的时候不允许其他任务执行。这时候dispatch_barrier就派上了用场。</p>
<p>使用dispatch_barrier将任务加入到并行队列之后,任务会在前面任务全部执行完成之后执行,任务执行过程中,其他任务无法执行,直到barrier任务执行完成。<br>一个常见的场景是属性的读写,例子如下:</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><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"> - (void)setName:(NSString *)name</span><br><span class="line">{</span><br><span class="line"> //写的时候阻塞住,等写操作结束后继续后续操作</span><br><span class="line"> dispatch_barrier_async(_concurrentQueue, ^{</span><br><span class="line"> _name = name;</span><br><span class="line"> });</span><br><span class="line">}</span><br><span class="line">- (NSString *)name</span><br><span class="line">{</span><br><span class="line"> __block NSString *localString;</span><br><span class="line"> dispatch_sync(_concurrentQueue, ^{</span><br><span class="line"> localString = _name;</span><br><span class="line"> });</span><br><span class="line"> return localString;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
<li><p>和NSOpration的区别</p>
</li>
</ul>
<p>###NSOpration</p>
<p>基于队列</p>
</div>
<div class="article-info article-info-index">
<div class="clearfix"></div>
</div>
</div>
</article>
</div>
<footer id="footer">
<div class="outer">
<div id="footer-info">
<div class="footer-left">
© 2016 Billy
<span id="busuanzi_container_site_pv">
本站总访问量<span id="busuanzi_value_site_pv"></span>次
本站访客数<span id="busuanzi_value_site_uv"></span>人次
</span>
</div>
<div class="footer-right">
<a href="http://hexo.io/" target="_blank">Hexo</a> Theme <a href="https://github.com/litten/hexo-theme-yilia" target="_blank">Yilia</a> by Litten
</div>
</div>
</div>
</footer>
</div>
<link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
<script>
var yiliaConfig = {
fancybox: true,
mathjax: true,
animate: undefined,
isHome: true,
isPost: false,
isArchive: false,
isTag: false,
isCategory: false,
open_in_new: undefined
}
</script>
<script src="http://7.url.cn/edu/jslib/comb/require-2.1.6,jquery-1.9.1.min.js"></script>
<script src="/js/main.js"></script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
processEscapes: true,
skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
}
});
MathJax.Hub.Queue(function() {
var all = MathJax.Hub.getAllJax(), i;
for(i=0; i < all.length; i += 1) {
all[i].SourceElement().parentNode.className += ' has-jax';
}
});
</script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
<script async src="https://dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js">
</script>
</div>
</body>
</html>