forked from aTreey/aTreey.github.io
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
944 lines (733 loc) · 111 KB
/
index.html
File metadata and controls
944 lines (733 loc) · 111 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>aTreey's Blog</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:type" content="website">
<meta property="og:title" content="aTreey's Blog">
<meta property="og:url" content="https://github.com/aTreey/index.html">
<meta property="og:site_name" content="aTreey's Blog">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="aTreey's Blog">
<link rel="alternate" href="/atom.xml" title="aTreey's Blog" type="application/atom+xml">
<link rel="icon" href="/favicon.png">
<link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<div id="container">
<div id="wrap">
<header id="header">
<div id="banner"></div>
<div id="header-outer" class="outer">
<div id="header-title" class="inner">
<h1 id="logo-wrap">
<a href="/" id="logo">aTreey's Blog</a>
</h1>
</div>
<div id="header-inner" class="inner">
<nav id="main-nav">
<a id="main-nav-toggle" class="nav-icon"></a>
<a class="main-nav-link" href="/">Home</a>
<a class="main-nav-link" href="/archives">Archives</a>
</nav>
<nav id="sub-nav">
<a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS Feed"></a>
<a id="nav-search-btn" class="nav-icon" title="Suche"></a>
</nav>
<div id="search-form-wrap">
<form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit"></button><input type="hidden" name="sitesearch" value="https://github.com/aTreey"></form>
</div>
</div>
</div>
</header>
<div class="outer">
<section id="main">
<article id="post-Swift错误处理" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2018/08/30/Swift错误处理/" class="article-date">
<time datetime="2018-08-30T01:51:40.641Z" itemprop="datePublished">2018-08-30</time>
</a>
</div>
<div class="article-inner">
<div class="article-entry" itemprop="articleBody">
<p>Swift 中错误处理</p>
<h3 id="assert-断言"><a href="#assert-断言" class="headerlink" title="assert 断言"></a>assert 断言</h3><p>只在debug 模式下程序会自动退出</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">public func assert(_ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = #file, line: UInt = #line)</span><br></pre></td></tr></table></figure>
<h3 id="assertionFailure-断言错误"><a href="#assertionFailure-断言错误" class="headerlink" title="assertionFailure 断言错误"></a>assertionFailure 断言错误</h3><p>只在debug 模式下程序会自动退出, 没有条件</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">public func assertionFailure(_ message: @autoclosure () -> String = default, file: StaticString = #file, line: UInt = #line)</span><br></pre></td></tr></table></figure>
<h3 id="precondition"><a href="#precondition" class="headerlink" title="precondition"></a>precondition</h3><p>releas 模式程序也会退出</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">public func precondition(_ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String = default, file: StaticString = #file, line: UInt = #line)</span><br></pre></td></tr></table></figure>
<p>### </p>
</div>
<footer class="article-footer">
<a data-url="https://github.com/aTreey/2018/08/30/Swift错误处理/" data-id="cjlgmf6nq001kbbfwzeb4ceyk" class="article-share-link">Teilen</a>
</footer>
</div>
</article>
<article id="post-Swift协议别名" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2018/08/25/Swift协议别名/" class="article-date">
<time datetime="2018-08-25T07:44:06.543Z" itemprop="datePublished">2018-08-25</time>
</a>
</div>
<div class="article-inner">
<div class="article-entry" itemprop="articleBody">
<p>Swift协议和别名</p>
<h3 id="协议"><a href="#协议" class="headerlink" title="协议"></a>协议</h3><p>某些属性的集合,可以有多个协议组成,具有的特点</p>
<ol>
<li>可以声明函数,但是不能实现,由实现这协议的具体结构或者类来实现</li>
<li>声明的函数如果有参数也不能设置参数的默认值, 默认参数被认为也是函的一种实现</li>
<li>可以声明属性,必须是计算型属性 只能使用var 修饰,不能是存储型属,必须在 {} 中明确指出属性的读取类型 例如 {get set}</li>
<li>遵守协议的类可选择存储型属性或者计算型属性来实现协议中定义的属性</li>
<li>protocol Person: class { } 表示此协议只能被类来遵守,结构体能遵守</li>
<li><p>协议可以看着是一种类型,如果协议中的属性是只读的,如果是协议类型只能访问get 方法, 但是遵守协议的具体类或者结构可以设置属性的读和写</p>
</li>
<li><p>协议中的构造函数</p>
<pre><code>- 如果父类中遵守了协议中的构造函数,子类中必须重写父类中的构造函数并且使用require修饰构造函数,表示继承此类的子类也必须实现该构造函数
- 如果class 使用了final 修饰,表示不能被继承,此时不需要 require 关键词修饰
</code></pre></li>
</ol>
<h3 id="类型别名"><a href="#类型别名" class="headerlink" title="类型别名"></a>类型别名</h3><ul>
<li><p>定义别名 <code>typealias</code>, 供扩展使用</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">typealias Length = Double</span><br><span class="line">extension Double {</span><br><span class="line"> var km: Length {return self * 1_000.0}</span><br><span class="line"> var m: Length {return self * 100.0}</span><br><span class="line"> var cm: Length {return self / 10.0}</span><br><span class="line"> /// 英尺</span><br><span class="line"> var ft: Length { return self / 3.28084}</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
</li>
</ul>
<pre><code>使用
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">let distance: Length = 10.5.km</span><br></pre></td></tr></table></figure>
</code></pre><ul>
<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"> // 音频采样率</span><br><span class="line">typealias AudioSample = UInt64</span><br></pre></td></tr></table></figure>
</li>
</ul>
<h3 id="协议中-typealias"><a href="#协议中-typealias" class="headerlink" title="协议中 typealias"></a>协议中 <code>typealias</code></h3><p><strong>协议中定义一个属性,该属性的类型根据不同的情况返回不同的类型(我理解为类似泛型),具体的类型由遵守此协议的类或者结构指定</strong></p>
<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><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">protocol WeightCalculable {</span><br><span class="line"> // 属性重量根据不同体积返回的可能是Int,可以可能是double类型,所以使用别名, 协议中使用associatedtype关键词,</span><br><span class="line"> associatedtype WeightType</span><br><span class="line"> var weight: WeightType { get }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>扩展 Int 中的吨单位</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">extension Int {</span><br><span class="line"> typealias Weight = Int</span><br><span class="line"> var t: Weight {return self * 1_000}</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<ul>
<li>使用协议中别名</li>
</ul>
<ul>
<li>一部手机的时使用该协议<code>WeightCalculable</code></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></pre></td><td class="code"><pre><span class="line">class iPhone: WeightCalculable {</span><br><span class="line"> typealias WeightType = Double</span><br><span class="line"> var weight: WeightType {</span><br><span class="line"> return 0.5</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<ul>
<li>一辆大卡时使用该协议<code>WeightCalculable</code></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></pre></td><td class="code"><pre><span class="line">class Car: WeightCalculable {</span><br><span class="line"> typealias WeightType = Int</span><br><span class="line"> let weight: WeightType</span><br><span class="line"> </span><br><span class="line"> init(weight: Int) {</span><br><span class="line"> self.weight = weight</span><br><span class="line"> }</span><br><span class="line">}</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">let bigCar = Car(weight: 8_000.t) // 8 吨</span><br></pre></td></tr></table></figure>
<h3 id="面向协议编程"><a href="#面向协议编程" class="headerlink" title="面向协议编程"></a>面向协议编程</h3><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><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">protocol Recordable: CustomStringConvertible {</span><br><span class="line"> var wins: Int { get }</span><br><span class="line"> var losses: Int { get }</span><br><span class="line"> </span><br><span class="line"> func winningPerent() -> Double</span><br><span class="line">}</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><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></pre></td><td class="code"><pre><span class="line">extension Recordable {</span><br><span class="line"> // CustomStringConvertible 协议默认实现</span><br><span class="line"> var description: String {</span><br><span class="line"> return String(format: "WINS: %d---LOSSES: %d", [wins, losses])</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> // 默认实现总场数计算型属性</span><br><span class="line"> var totalGames: Int {</span><br><span class="line"> return wins + losses</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> // 默认实现的方法</span><br><span class="line"> func shoutWins() {</span><br><span class="line"> print("come on", wins, "times!")</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h4 id="篮球比赛:"><a href="#篮球比赛:" class="headerlink" title="篮球比赛:"></a>篮球比赛:</h4><ul>
<li>Equatable 协议 - 相等比较 需要重载 <code>==</code></li>
<li>Comparable 协议 - 是否可比较 ,重载 <code><</code> 可直接调用sort()函数</li>
<li>CustomStringConvertible 协议 - 打印信息,需重写 <code>description</code></li>
<li>Recordable协议 - 比赛协议,没有平局 </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><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></pre></td><td class="code"><pre><span class="line">struct BasketballRecord:Equatable, Comparable, CustomStringConvertible, Recordable {</span><br><span class="line"> var wins: Int</span><br><span class="line"> var losses: Int</span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"> /// 在具体定义的类型中实现 协议中的属性或者方法就会覆盖协议中的</span><br><span class="line"> var totalGames: Int = 200</span><br><span class="line"> </span><br><span class="line"> var description: String {</span><br><span class="line"> return "本次比赛胜: " + String(wins) + "负" + "\(losses)"</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> // 胜率</span><br><span class="line"> func winningPerent() -> Double {</span><br><span class="line"> return (Double(wins) / Double(totalGames))</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> // swift4.1 后,不需要再重写此方法,swift 会自动合成,如果不想让某一个属性参与比较,就需要重写该方法</span><br><span class="line"> static func == (lhs: BasketballRecord, rhs: BasketballRecord) -> Bool {</span><br><span class="line"> return lhs.wins == rhs.wins && lhs.losses == rhs.losses</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> // Comparable</span><br><span class="line"> static func < (lhs: BasketballRecord, rhs: BasketballRecord) -> Bool {</span><br><span class="line"> if lhs.wins != rhs.wins {</span><br><span class="line"> return lhs.wins < rhs.wins</span><br><span class="line"> }</span><br><span class="line"> return lhs.losses > rhs.losses</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><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>protocol Tieable {<br> /// 平局,可读写<br> var ties: Int { get set }</p>
<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></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">- 足球比赛需要遵守的协议 `Recordable` 和 `Tieable`</span><br><span class="line"></span><br><span class="line"> - 总场数需要加上平局的场数,需要实现totalGames的get方法</span><br></pre></td></tr></table></figure></p>
<p>struct FootableRecord: Recordable, Tieable {<br> var wins: Int<br> var losses: Int<br> // 平局数<br> var ties: Int</p>
<pre><code>// 总场数
var totalGames: Int {
return wins + losses + ties
}
var description: String {
return "本次比赛胜: " + String(wins) + "负" + "\(losses)"
}
func winningPerent() -> Double {
return (Double(wins) / Double(totalGames))
}
</code></pre><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><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"></span><br><span class="line">- 足球比赛中以上写法存在的问题</span><br><span class="line"> </span><br><span class="line"> - 所有有平局的比赛计算总场次的逻辑都是一样,每次都要写一次实现</span><br><span class="line"> - 单一修改 Recordable 协议不能解决问题,</span><br><span class="line"> - 存在平局和没有平局两种情况 totalGames 的计算逻辑不相同 </span><br><span class="line"></span><br><span class="line">- 解决办法:</span><br><span class="line"> - 扩展遵守了`Recordable`协议的类型,前提条件是:这个类型遵守了 Tieable 同时也遵守了 `Recordable ` 协议,可以理解为如果该类型遵守了 `Tieable `协议之后,`Recordable` 协议中的 totalGames 属性实现是另一种方式了,不在是以前的 `totalGames` 中直接返回 `wins + losses` 的值</span><br><span class="line"> </span><br><span class="line"></span><br><span class="line">定义协议</span><br></pre></td></tr></table></figure></p>
<p>protocol Recordable: CustomStringConvertible {<br> var wins: Int { get }<br> var losses: Int { get }</p>
<pre><code>func winningPerent() -> Double
</code></pre><p>}<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">协议默认实现</span><br></pre></td></tr></table></figure></p>
<p>extension Recordable {<br> var description: String {<br> return String(format: “WINS: %d—LOSSES: %d”, [wins, losses])<br> }</p>
<pre><code>// 默认实现总场数计算型属性
var totalGames: Int {
return wins + losses
}
// 默认实现胜率
func winningPerent() -> Double {
return (Double(wins) / Double(totalGames))
}
// 默认实现的方法
func shoutWins() {
print("come on", wins, "times!")
}
</code></pre><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"></span><br><span class="line">扩展遵守了Tieable 的 类型的 Recordable 协议</span><br></pre></td></tr></table></figure>
<p>extension Recordable where Self: Tieable {<br> var totalGames: Int {<br> return wins + losses + ties<br> }<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></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>protocol Prizable {<br> func isPrizable() -> Bool<br>}</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"></span><br><span class="line">篮球比赛遵守此协议</span><br></pre></td></tr></table></figure>
<p>// 篮球比赛奖赏<br>extension BasketballRecord: Prizable {<br> func isPrizable() -> Bool {<br> return totalGames > 10 && winningPerent() > 0.5<br> }<br>}</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"></span><br><span class="line">足球比赛奖赏遵守此协议</span><br></pre></td></tr></table></figure>
<p>extension FootableRecord: Prizable {<br> func isPrizable() -> Bool {<br> return wins > 1<br> }<br>}<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">现在有某一个学生也遵守了此协议</span><br></pre></td></tr></table></figure></p>
<p>struct Student: Prizable {<br> var name: String<br> var score: Int</p>
<pre><code>func isPrizable() -> Bool {
return score >= 60
}
</code></pre><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"></span><br><span class="line">定义奖赏的方法,参数类型必须是遵守了此协议的结构或者类型</span><br></pre></td></tr></table></figure>
<p>private func award(_ one: Prizable) {<br> if one.isPrizable() {<br> print(one)<br> print(“恭喜获得奖励”)<br> } else {<br> print(one)<br> print(“很遗憾”)<br> }<br>}<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">如果说 BasketballRecord 这个类还遵守了其他的协议,例如遵守了 `Recordable` 协议, 并且这个协议也遵守了 `CustomStringConvertible` 并且默认实现了`description` 的`get` 方法</span><br></pre></td></tr></table></figure></p>
<p>// MARK: - 比赛协议,具有 赢。输。总场次。胜率 特性<br>protocol Recordable: CustomStringConvertible {<br> var wins: Int { get }<br> var losses: Int { get }</p>
<pre><code>func winningPerent() -> Double
</code></pre><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"></span><br><span class="line">`Recordable` 默认实现</span><br></pre></td></tr></table></figure>
<p>extension Recordable {<br> var description: String {<br> return String(format: “WINS: %d—LOSSES: %d”, [wins, losses])<br> }</p>
<pre><code>// 默认实现总场数计算型属性
var totalGames: Int {
return wins + losses
}
// 默认实现胜率
func winningPerent() -> Double {
return (Double(wins) / Double(totalGames))
}
// 默认实现的方法
func shoutWins() {
print("come on", wins, "times!")
}
</code></pre><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"></span><br><span class="line">此时如果 `Student` 类还是调用 `award` 方法的话,print(one) 打印的信息将是`Recordable `中默认实现的内容,因此需要约束`award`函数的参数必须遵守两个协议让`Student` 也重写自己的`description `属性的`get`方法,不能再让 `Prizable` 扩展 默认实现</span><br><span class="line"></span><br><span class="line">- swift 3 写法: protocol<A, B></span><br><span class="line">- swift 4 写法: A & B</span><br></pre></td></tr></table></figure></p>
<p>private func award2(_ one: Prizable & CustomStringConvertible) {<br> if one.isPrizable() {<br> print(one)<br> print(“恭喜获得奖励”)<br> } else {<br> print(one)<br> print(“很遗憾”)<br> }<br>}<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></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"> - 参数:一个学生数组,都遵守了 Comparable 的类型</span><br><span class="line"> - 返回值:某个遵守了 Comparable 的类型实例</span><br><span class="line"> - 此时函数报错 `Protocol 'Comparable' can only be used as a generic constraint because it has Self or associated type requirements`, </span><br><span class="line"> </span><br><span class="line"> 因为 Comparable 协议中定义的方法 public static func < (lhs: Self, rhs: Self) -> Bool 的参数类型是Self,是具体的某个类型</span><br></pre></td></tr></table></figure></p>
<p>func maxScore(seq: [Comparable]) -> Comparable { }<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"></span><br><span class="line"></span><br><span class="line">- 如果需要定义一个函数实现在一个数组中找出需要奖励的人的名字该如何实现呢</span><br><span class="line"> - 参数:遵守两个协议 Comparable 和 Prizable 协议, 并且使用泛型</span><br><span class="line"> - 返回值:返回值是可选值,有可能没有任何奖励的对象</span><br></pre></td></tr></table></figure></p>
<p>func topPrizable<T: Comparable & Prizable>(seq: [T]) -> T? {<br> return seq.reduce(nil) { (tempTop: T?, condender: T) in<br> guard condender.isPrizable() else { return tempTop }<br> // 解包 condender 失败, 上一层验证了他必须是奖励的那个<br> guard let tempTop = tempTop else { return condender }<br> return max(tempTop, condender)<br> }<br>}</p>
<p><code>`</code></p>
</div>
<footer class="article-footer">
<a data-url="https://github.com/aTreey/2018/08/25/Swift协议别名/" data-id="cjlgmf6oq002ibbfw0tpp698w" class="article-share-link">Teilen</a>
</footer>
</div>
</article>
<article id="post-Swift协议扩展" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2018/08/25/Swift协议扩展/" class="article-date">
<time datetime="2018-08-25T07:24:46.789Z" itemprop="datePublished">2018-08-25</time>
</a>
</div>
<div class="article-inner">
<div class="article-entry" itemprop="articleBody">
<p>Swift协议扩展</p>
<h3 id="定义结构体"><a href="#定义结构体" class="headerlink" title="定义结构体"></a>定义结构体</h3><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">struct Point {</span><br><span class="line"> var x = 0.0</span><br><span class="line"> var y = 0.0</span><br><span class="line"> </span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">struct Size {</span><br><span class="line"> var height = 0.0</span><br><span class="line"> var width = 0.0</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">struct Rectangle {</span><br><span class="line"> var origin = Point()</span><br><span class="line"> var size = Size()</span><br><span class="line"> </span><br><span class="line"> init(origin: Point, size: Size) {</span><br><span class="line"> self.origin = origin</span><br><span class="line"> self.size = size</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="扩展"><a href="#扩展" class="headerlink" title="扩展"></a>扩展</h3><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><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">extension Rectangle {</span><br><span class="line"> mutating func translate(x: Double, y: Double) {</span><br><span class="line"> self.origin.x += x</span><br><span class="line"> self.origin.y += y</span><br><span class="line"> }</span><br><span class="line">}</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><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></pre></td><td class="code"><pre><span class="line">extension Rectangle {</span><br><span class="line"> var center: Point {</span><br><span class="line"> get {</span><br><span class="line"> let center_x = origin.x + size.width / 2.0</span><br><span class="line"> let center_y = origin.y + size.height / 2.0</span><br><span class="line"> return Point(x: center_x, y: center_y)</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> set {</span><br><span class="line"> origin.x = newValue.x - size.width / 2.0</span><br><span class="line"> origin.y = newValue.y - size.height / 2.0</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<ul>
<li><p>扩展构造方法</p>
<ul>
<li>类中不能扩展指定构造方法,只能在结构体中扩展</li>
<li>结构体中不能扩展便利构造方法m,只能在类中扩展</li>
</ul>
</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></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">extension Rectangle {</span><br><span class="line"> init(center: Point, size: Size) {</span><br><span class="line"> let origin_x = center.x - size.width / 2.0</span><br><span class="line"> let origin_y = center.y - size.height / 2.0</span><br><span class="line"> self.origin = Point(x: origin_x, y: origin_y)</span><br><span class="line"> self.size = size</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> // 结构体中不能扩展便利构造函数 Delegating initializers in structs are not marked with 'convenience'</span><br><span class="line">// convenience init(center: Point, size: Size) {</span><br><span class="line">// let origin_x = center.x - size.width / 2.0</span><br><span class="line">// let origin_y = center.y - size.height / 2.0</span><br><span class="line">// self.origin = Point(x: origin_x, y: origin_y)</span><br><span class="line">// self.size = size</span><br><span class="line">// }</span><br><span class="line">}</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><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></pre></td><td class="code"><pre><span class="line">extension Rectangle {</span><br><span class="line"> enum Vertex: Int {</span><br><span class="line"> case left_top</span><br><span class="line"> case left_bottom</span><br><span class="line"> case right_bottom</span><br><span class="line"> case right_top</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> // 获取某一个顶点坐标</span><br><span class="line"> func point(of vertex: Vertex) -> Point {</span><br><span class="line"> switch vertex {</span><br><span class="line"> case .left_top:</span><br><span class="line"> return origin</span><br><span class="line"> case .left_bottom:</span><br><span class="line"> return Point(x: origin.x, y: origin.y + size.height)</span><br><span class="line"> case .right_bottom:</span><br><span class="line"> return Point(x: origin.x + size.width, y: origin.y + size.height)</span><br><span class="line"> case .right_top:</span><br><span class="line"> return Point(x: origin.x + size.width, y: origin.y)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</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><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">extension Rectangle {</span><br><span class="line"> subscript(index: Int) -> Point? {</span><br><span class="line"> assert(0 <= index && index < 4, "传入值非法")</span><br><span class="line"> return point(of: Vertex(rawValue: index)!)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="扩展系统方法"><a href="#扩展系统方法" class="headerlink" title="扩展系统方法"></a>扩展系统方法</h3><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></pre></td><td class="code"><pre><span class="line">extension Int {</span><br><span class="line"> /// 平方</span><br><span class="line"> var square: Int {</span><br><span class="line"> return self * self</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> /// 立方</span><br><span class="line"> var cube: Int {</span><br><span class="line"> return self * self * self</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> /// 判断数组是否在某一个范围内</span><br><span class="line"> func inRange(clousedLeft left: Int, openRight right: Int) -> Bool {</span><br><span class="line"> return self >= left && self > right</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> /// 重复执行操作</span><br><span class="line"> func repeatitions(task: () -> ()) {</span><br><span class="line"> for _ in 0..<self {</span><br><span class="line"> task()</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"> func stride(from: Int, to: Int, by: Int, task: () -> ()) {</span><br><span class="line"> // 系统变长函数</span><br><span class="line"> for i in Swift.stride(from: 0, to: 21, by: 3) {</span><br><span class="line"> print(i)</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> for _ in Swift.stride(from: from, to: to, by: by) {</span><br><span class="line"> task()</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">print(2.square)</span><br><span class="line">print(3.cube)</span><br><span class="line">print(4.inRange(clousedLeft: 0, openRight: 4))</span><br><span class="line">4.repeatitions {</span><br><span class="line"> print("extension")</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">4.stride(from: 0, to: 8, by: 4) {</span><br><span class="line"> print("stride")</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
</div>
<footer class="article-footer">
<a data-url="https://github.com/aTreey/2018/08/25/Swift协议扩展/" data-id="cjlgmf6nm001gbbfw264nzpuf" class="article-share-link">Teilen</a>
</footer>
</div>
</article>
<article id="post-Swift下标和运算符重载" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2018/08/25/Swift下标和运算符重载/" class="article-date">
<time datetime="2018-08-25T05:37:16.050Z" itemprop="datePublished">2018-08-25</time>
</a>
</div>
<div class="article-inner">
<div class="article-entry" itemprop="articleBody">
<p>Swift下标和运算符重载</p>
<h3 id="字典数组下标"><a href="#字典数组下标" class="headerlink" title="字典数组下标"></a>字典数组下标</h3><pre><code>var array = [1,2,3,4,5,6]
let temp = array[0] // 通过下标访问
let temp2 = array[2] // 通过下标访问
</code></pre><h3 id="结构体下标"><a href="#结构体下标" class="headerlink" title="结构体下标"></a>结构体下标</h3><ul>
<li><p>对于结构体不是直接使用下标访问,会直接报错<br>直接使用下标获取属性值报错: <code>Type 'Vector_3' has no subscript members</code></p>
</li>
<li><p>可以通过实现 <code>subscript(index: Int) -> Double?</code>方法让结构体支持下标访问,可以理解为一个特殊的函数,需要传入参数和返回值</p>
</li>
<li>可以增加第二种下标–根据坐标轴获取属性值</li>
<li>重写 subscript 的 set 方法 可以使用下标修改属性值</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><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><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line">struct Vector_3 {</span><br><span class="line"> var x = 0.0</span><br><span class="line"> var y = 0.0</span><br><span class="line"> var z = 0.0</span><br><span class="line"> </span><br><span class="line"> // 根据索引获取</span><br><span class="line"> subscript(index: Int) -> Double? {</span><br><span class="line"> </span><br><span class="line"> // 重写了get方法 实现通过下标获取属性值</span><br><span class="line"> get {</span><br><span class="line"> switch index {</span><br><span class="line"> case 0: return x</span><br><span class="line"> case 1: return y</span><br><span class="line"> case 2: return z</span><br><span class="line"> default: return nil</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> // 重写 set 方法,实现g通过下标设置属性值,使用系统默认的newValue</span><br><span class="line"> set {</span><br><span class="line"> guard let newValue = newValue else {return}</span><br><span class="line"> switch index {</span><br><span class="line"> case 0: x = newValue</span><br><span class="line"> case 1: y = newValue</span><br><span class="line"> case 2: z = newValue</span><br><span class="line"> default: return</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><span class="line"> subscript(axis: String) -> Double? {</span><br><span class="line"> </span><br><span class="line"> get {</span><br><span class="line"> switch axis {</span><br><span class="line"> case "X", "x": return x</span><br><span class="line"> case "Y", "y": return y</span><br><span class="line"> case "Z", "z": return z</span><br><span class="line"> default: return nil</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> set {</span><br><span class="line"> guard let newValue = newValue else {return}</span><br><span class="line"> switch axis {</span><br><span class="line"> case "X", "x": x = newValue</span><br><span class="line"> case "Y", "y": y = newValue</span><br><span class="line"> case "Z", "z": z = newValue</span><br><span class="line"> default: return</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><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>var v = Vector_3(x: 1, y: 2, z: 3)<br>print(v[0], v[1], v[2], v[3], v[100]) // Optional(1.0) Optional(2.0) Optional(3.0) nil nil<br>print(v[“x”], v[“y”], v[“z”], v[“i”]) // Optional(1.0) Optional(2.0) Optional(3.0) nil</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"></span><br><span class="line">结构体使用下标修改值</span><br></pre></td></tr></table></figure>
<p>v[0] = 101<br>v[1] = 202<br>v[2] = 303<br>v[3] = 400<br>v[100] = 51<br>print(v[0], v[1], v[2], v[3], v[100]) // Optional(101.0) Optional(202.0) Optional(303.0) nil nil<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>v[“x”] = 100<br>v[“y”] = 200<br>v[“z”] = 300<br>v[“i”] = 50<br>print(v[“x”], v[“y”], v[“z”], v[“i”]) // Optional(100.0) Optional(200.0) Optional(300.0) nil</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><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></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"> struct Matrix {</span><br><span class="line"> var data: [[Double]]</span><br><span class="line"> let row: Int</span><br><span class="line"> let column: Int</span><br><span class="line"> </span><br><span class="line"> init(row: Int, column: Int) {</span><br><span class="line"> self.row = row</span><br><span class="line"> self.column = column</span><br><span class="line"> data = [[Double]]()</span><br><span class="line"> for _ in 0..<row {</span><br><span class="line"> let aRow = Array(repeating: 1.0, count: column)</span><br><span class="line"> data.append(aRow)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> // 通过下标 [row,column] 方式访问</span><br><span class="line"> subscript(row: Int, column: Int) -> Double {</span><br><span class="line"> get {</span><br><span class="line"> assert(row >= 0 && row < self.row && column >= 0 && column < self.column, "下标不合法")</span><br><span class="line"> return data[row][column]</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> set {</span><br><span class="line"> assert(row >= 0 && row < self.row && column >= 0 && column < self.column, "下标不合法")</span><br><span class="line"> data[row][column] = newValue</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> // 通过下标 [row][column] 方式访问</span><br><span class="line"> subscript(row: Int) -> [Double] {</span><br><span class="line"> get {</span><br><span class="line"> assert(row >= 0 && row < self.row, "下标不合法")</span><br><span class="line"> // 直接返回数组,数组本身有下标</span><br><span class="line"> return data[row]</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> set {</span><br><span class="line"> assert(newValue.count == column, "下标不合法")</span><br><span class="line"> data[row] = newValue</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><span class="line">### 运算符重载</span><br><span class="line"> </span><br><span class="line">- 重载 + 运算符</span><br></pre></td></tr></table></figure>
<p>func +(one: Vector_3, other: Vector_3) -> Vector_3 {<br> return Vector_3(x: one[0]! + other[0]!, y: one[1]! + other[1]!, z: one[2]! + other[2]!)</p>
<p>// return Vector_3(x: one.x + other.x, y: one.y + other.y, z: one.z + other.z)<br>}</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"></span><br><span class="line">- 两个参数时相减</span><br></pre></td></tr></table></figure>
<p>func -(one: Vector_3, other: Vector_3) -> Vector_3 {<br> return Vector_3(x: one.x - other.x, y: one.y - other.y, z: one.z - other.z)<br>}</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">- 一个参数时去反, 需要 prefix 修饰</span><br></pre></td></tr></table></figure>
<p>prefix func -(a: Vector_3) -> Vector_3 {<br> return Vector_3(x: -a.x, y: -a.y, z: -a.z)<br>}<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">- 向量相乘/向量和常量相乘</span><br></pre></td></tr></table></figure></p>
<p>func <em>(one: Vector_3, other: Vector_3) -> Double {<br> return (one.x </em> other.x) + (one.y <em> other.y) + (one.z </em> other.z)<br>}</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"></span><br><span class="line">- 两个参数不能交换,需要重载两次 `*`</span><br></pre></td></tr></table></figure>
<p>func <em>(one: Vector_3, a: Double) -> Vector_3 {<br> return Vector_3(x: a </em> one.x, y: a <em> one.y, z: a </em> one.z)<br>}</p>
<p>func <em>(a: Double, one: Vector_3) -> Vector_3 {<br> return one </em> a</p>
<pre><code>// 也可采用下面写法
</code></pre><p>// return Vector_3(x: a <em> one.x, y: a </em> one.y, z: a * one.z)<br>}</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"></span><br><span class="line">- 修改自身参数,不需要返回值</span><br></pre></td></tr></table></figure>
<p>func +=(one: inout Vector_3, other: Vector_3) {<br> // 已经重载过 + 运算符,可以直接调用<br> one = one + other<br>}</p>
<p>func ==(one: Vector_3, other: Vector_3) -> Bool {<br> return one.x == other.x &&<br> one.y == other.y &&<br> one.z == other.z<br>}</p>
<p>func !=(one: Vector_3, other: Vector_3) -> Bool {<br> return !(one == other)</p>
<pre><code>// 也可采用下面写法
return one.x != other.x ||
one.y != other.y ||
one.z != other.z
</code></pre><p>}</p>
<p>func <(one: Vector_3, other: Vector_3) -> Bool {<br> if one.x != other.x {return one.x < other.x}<br> if one.y != other.y {return one.y < other.y}<br> if one.z != other.z {return one.z < other.z}<br> return false<br>}</p>
<p>func <=(one: Vector_3, other: Vector_3) -> Bool {<br> return one < other || one == other</p>
<pre><code>// 也可采用下面写法
return one.x > other.x &&
one.y > other.x &&
one.z > other.z
</code></pre><p>}</p>
<p>func >(one: Vector_3, other: Vector_3) -> Bool {<br> return (one <= other)<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></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">### 自定义操作符</span><br><span class="line"></span><br><span class="line">`postfix` 声明前后缀关键词, `operator ` 操作符关键词</span><br><span class="line"></span><br><span class="line">- a+++</span><br></pre></td></tr></table></figure>
<p>声明后置操作符<br>postfix operator +++<br>postfix func +++(vector: inout Vector_3) -> Vector_3 {<br> vector += Vector_3(x: 1.0, y: 1.0, z: 1.0)<br> return vector<br>}</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"></span><br><span class="line">- +++a</span><br></pre></td></tr></table></figure>
<p>// 声明前置操作符<br>prefix operator +++<br>prefix func +++(vector: inout Vector_3) -> Vector_3 {<br> let temp = vector<br> vector += Vector_3(x: 1.0, y: 1.0, z: 1.0)<br> return temp<br>}</p>
<p><code>`</code></p>
</div>
<footer class="article-footer">
<a data-url="https://github.com/aTreey/2018/08/25/Swift下标和运算符重载/" data-id="cjlgmf6nk001cbbfw8l1uj5ya" class="article-share-link">Teilen</a>
</footer>
</div>
</article>
<article id="post-iOS通过URL获取HTML中标题" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2018/08/22/iOS通过URL获取HTML中标题/" class="article-date">
<time datetime="2018-08-22T15:59:33.206Z" itemprop="datePublished">2018-08-22</time>
</a>
</div>
<div class="article-inner">
<div class="article-entry" itemprop="articleBody">
<p>iOS通过URL获取HTML中标题</p>
<h3 id="获取标题"><a href="#获取标题" class="headerlink" title="获取标题"></a>获取标题</h3><h5 id="String扩展一个方法"><a href="#String扩展一个方法" class="headerlink" title="String扩展一个方法"></a>String扩展一个方法</h5><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">private let patternTitle = "(?<=title>).*(?=</title)"</span><br><span class="line">extension String {</span><br><span class="line"> static func parseHTMLTitle(_ urlString: String) -> String? {</span><br><span class="line"> let url = URL(string: urlString)!</span><br><span class="line"> do {</span><br><span class="line"> let html = try String(contentsOf: url, encoding: .utf8)</span><br><span class="line"> let range = html.range(of: patternTitle, options: String.CompareOptions.regularExpression, range: html.startIndex..<html.endIndex, locale: nil)</span><br><span class="line"> guard let tempRange = range else { return "" }</span><br><span class="line"> let titleStr = html[tempRange]</span><br><span class="line"> return String(titleStr)</span><br><span class="line"> } catch {</span><br><span class="line"> return ""</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h5 id="iOS-中简单正则表达式"><a href="#iOS-中简单正则表达式" class="headerlink" title="iOS 中简单正则表达式"></a>iOS 中简单正则表达式</h5><p>iOS 中 正则表达式中的\ 需要使用 \\ 来表示</p>
<pre><code>// 获取
let testStr = "我到底是[iOS]开发还是[产品]经理"
// 获取 "[" 和 "]" 之间的所有内容, 左边[ 起一直到 右边 ] 结束的所有内容
let pattern1 = "\\[.*\\]" // [iOS]开发还是[产品]
// 获取 "[" 和 "]" 之间的所有内容,包括[]
let pattern2 = "\\[.*?\\]" // [iOS]
// 获取第一个 "[" 和 "]" 之间的所有内容 不包括[]
let pattern3 = "(?<=\\[).*?(?=\\])" // iOS
// 获取html中 title 标签中内容
let pattern5 = "(?<=title>).*(?=</title)"
</code></pre><h5 id="获取范围截取子串"><a href="#获取范围截取子串" class="headerlink" title="获取范围截取子串"></a>获取范围截取子串</h5><pre><code>let testRange1 = testStr.range(of: pattern1, options: String.CompareOptions.regularExpression, range: testStr.startIndex..<testStr.endIndex, locale: nil)
let result1 = String(testStr[testRange1!])
let testRange2 = testStr.range(of: pattern2, options: String.CompareOptions.regularExpression, range: testStr.startIndex..<testStr.endIndex, locale: nil)
let result2 = String(testStr[testRange2!])
let testRange3 = testStr.range(of: pattern3, options: String.CompareOptions.regularExpression, range: testStr.startIndex..<testStr.endIndex, locale: nil)
let result3 = String(testStr[testRange3!])
print(result1)
print(result2)
print(result3)
</code></pre><h5 id="正则表达式"><a href="#正则表达式" class="headerlink" title="正则表达式"></a>正则表达式</h5><p>通过URL解析html中的标题</p>
<ul>
<li>获取html字符串</li>
<li>正则匹配</li>
<li>生成字符串Range</li>
<li>截取字符串</li>
</ul>
<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></pre></td><td class="code"><pre><span class="line">// 生成表达式</span><br><span class="line">let regular = try NSRegularExpression(pattern: pattern5, options: .caseInsensitive) </span><br><span class="line"> </span><br><span class="line"></span><br><span class="line">// 开始匹配 </span><br><span class="line">let matchResult1 = regular.firstMatch(in: html, options: NSRegularExpression.MatchingOptions.reportProgress, range: NSMakeRange(0, html.count))</span><br><span class="line"></span><br><span class="line">// 获取匹配结果范围</span><br><span class="line">let matchRange = matchResult1?.range</span><br><span class="line">let range = Range(matchRange!)!</span><br><span class="line"> </span><br><span class="line">// 生成String.Index 类型范围 </span><br><span class="line">let startIndex = html.index(html.startIndex, offsetBy: range.lowerBound)</span><br><span class="line">let endIndex = html.index(html.startIndex, offsetBy: range.upperBound)</span><br><span class="line">let range3 = Range(uncheckedBounds: (lower: startIndex, upper: endIndex))</span><br><span class="line"></span><br><span class="line">// 截取字符串</span><br><span class="line">let result1 = String(html[range3])</span><br><span class="line">print(result1)</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">let matchResult2 = regular.matches(in: html, options: .reportProgress, range: NSMakeRange(0, html.count))</span><br><span class="line"> matchResult2.forEach { (result) in</span><br><span class="line">let range = Range(result.range)!</span><br><span class="line"> </span><br><span class="line">let startIndex = html.index(html.startIndex, offsetBy: range.lowerBound)</span><br><span class="line">let endIndex = html.index(html.startIndex, offsetBy: range.upperBound)</span><br><span class="line"> </span><br><span class="line">let subStr2 = html[Range(uncheckedBounds: (startIndex, endIndex))]</span><br><span class="line">print(String(subStr2))</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></pre></td><td class="code"><pre><span class="line">let str3 = regular.stringByReplacingMatches(in: html, options: .reportProgress, range: NSMakeRange(0, html.count), withTemplate: "====")</span><br></pre></td></tr></table></figure>
</div>
<footer class="article-footer">
<a data-url="https://github.com/aTreey/2018/08/22/iOS通过URL获取HTML中标题/" data-id="cjlgmf6ny001ybbfwm7qjvcbz" class="article-share-link">Teilen</a>
</footer>
</div>
</article>
<article id="post-GCD 信号量" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2018/08/17/GCD 信号量/" class="article-date">
<time datetime="2018-08-16T17:37:15.429Z" itemprop="datePublished">2018-08-17</time>
</a>
</div>
<div class="article-inner">
<div class="article-entry" itemprop="articleBody">
<p>GCD信号量用法</p>
<p>对于异步网络请求相互依赖问题一般用三种方式解决:</p>
<ul>
<li>网络请求嵌套</li>
<li>使用 BlockOperation </li>
<li>GCD DispatchGroup</li>
<li>GCD semaphore(信号量)</li>
</ul>
<h3 id="GCD-信号量"><a href="#GCD-信号量" class="headerlink" title="GCD 信号量"></a>GCD 信号量</h3><ul>
<li>semaphore 值 <= 0 阻塞</li>
<li>semaphore semaphore.signal() 使信号量值增加</li>
<li>semaphore.wait() 等待,可设置时长</li>
</ul>
<p>request – 3 依赖 request – 1 和 request – 2,1 和 2 无需关注顺序</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></pre></td><td class="code"><pre><span class="line">private func gcdSemaphore() {</span><br><span class="line"> let semaphore = DispatchSemaphore(value: 0)</span><br><span class="line"> DispatchQueue.global().async {</span><br><span class="line"> for i in 0...300 {</span><br><span class="line"> print("request -- 1")</span><br><span class="line"> }</span><br><span class="line"> semaphore.signal()</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> DispatchQueue.global().async {</span><br><span class="line"> for i in 0...200 {</span><br><span class="line"> print("request -- 2")</span><br><span class="line"> }</span><br><span class="line"> semaphore.signal()</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"> DispatchQueue.global().async {</span><br><span class="line"> semaphore.wait()</span><br><span class="line"> semaphore.wait()</span><br><span class="line"> for i in 0...160 {</span><br><span class="line"> print("request -- 3")</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
<p>request – 3 ,request – 2 和 request – 1,依次相互依赖</p>
<pre><code>private func gcdSemaphore() {
let semaphore = DispatchSemaphore(value: 0)
DispatchQueue.global().async {
for i in 0...300 {
print("request -- 1")
}
semaphore.signal()
}
DispatchQueue.global().async {
semaphore.wait()
for i in 0...200 {
print("request -- 2")
}
semaphore.signal()
}
DispatchQueue.global().async {
semaphore.wait()
for i in 0...160 {
print("request -- 3")
}
}
}
</code></pre>
</div>
<footer class="article-footer">
<a data-url="https://github.com/aTreey/2018/08/17/GCD 信号量/" data-id="cjlgmf6mn0003bbfwxoap0am5" class="article-share-link">Teilen</a>
</footer>
</div>
</article>
<article id="post-ReactNative中ref使用" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2018/07/26/ReactNative中ref使用/" class="article-date">
<time datetime="2018-07-26T15:05:32.640Z" itemprop="datePublished">2018-07-26</time>
</a>
</div>
<div class="article-inner">
<div class="article-entry" itemprop="articleBody">
<p>Reat Native ref 使用</p>
<h3 id="State-状态的使用"><a href="#State-状态的使用" class="headerlink" title="State 状态的使用"></a>State 状态的使用</h3><p>在父控件中指定,整个生命周期讲不再改变<br>需求:一段闪烁的文字, Props 属性显示文字内容创建时初始化,State控制随时间变化是否显示,在父控件中</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></pre></td><td class="code"><pre><span class="line">class Blink extends Component{</span><br><span class="line"> // 构造</span><br><span class="line"> constructor(props) {</span><br><span class="line"> super(props);</span><br><span class="line"> // 初始状态</span><br><span class="line"> this.state = {showWithText:true};</span><br><span class="line"> this.state = {}</span><br><span class="line"> setInterval(() => {</span><br><span class="line"> this.setState(previousState => {</span><br><span class="line"> return {showWithText: !previousState.showWithText}</span><br><span class="line"> });</span><br><span class="line"> }, 100);</span><br><span class="line"> }</span><br><span class="line"> render() {</span><br><span class="line"> let display= this.state.showWithText ? this.props.text : ' ';</span><br><span class="line"> return(</span><br><span class="line"> <Text>{display}</Text></span><br><span class="line"> );</span><br><span class="line"> }</span><br><span class="line">}</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><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></pre></td><td class="code"><pre><span class="line">export default class App extends Component<Props> {</span><br><span class="line"> render() {</span><br><span class="line"> return(</span><br><span class="line"> <View style={styles.container}></span><br><span class="line"> <Blink</span><br><span class="line"> text='I love to blink'</span><br><span class="line"> /></span><br><span class="line"></span><br><span class="line"> <Blink</span><br><span class="line"> text='猜猜猜'</span><br><span class="line"> /></span><br><span class="line"></span><br><span class="line"> <Blink</span><br><span class="line"> text='Blink is great'</span><br><span class="line"> /></span><br><span class="line"> </View></span><br><span class="line"> );</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="Props-属性的使用"><a href="#Props-属性的使用" class="headerlink" title="Props 属性的使用"></a>Props 属性的使用</h3><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></pre></td><td class="code"><pre><span class="line">// 定义一个组件</span><br><span class="line">class Greeting extends Component {</span><br><span class="line"> render() {</span><br><span class="line"> return(</span><br><span class="line"> <Text> Hello {this.props.name}!</span><br><span class="line"> </Text></span><br><span class="line"> );</span><br><span class="line"> }</span><br><span class="line">}</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><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">export default class App extends Component<Props> {</span><br><span class="line"> render() {</span><br><span class="line"> return(</span><br><span class="line"> <View style={styles.container}></span><br><span class="line"> <Image source={{uri:'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'}}</span><br><span class="line"> style={{width: 190, height: 110}}</span><br><span class="line"> /></span><br><span class="line"> <Text style={styles.instructions}></span><br><span class="line"> 使用Props属性</span><br><span class="line"> </Text></span><br><span class="line"> <View></span><br><span class="line"> <Greeting name='React-Native'</span><br><span class="line"> /></span><br><span class="line"> <Greeting name='iOS'</span><br><span class="line"> /></span><br><span class="line"> <Greeting name='Swift'</span><br><span class="line"> /></span><br><span class="line"> </View></span><br><span class="line"></span><br><span class="line"> </View></span><br><span class="line"> );</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h4 id="ref的使用"><a href="#ref的使用" class="headerlink" title="ref的使用"></a>ref的使用</h4><ul>
<li>可以理解为组件渲染后指向组件的一个应用,可以通过ref获取到真实的组件(类似指针?)</li>
</ul>
<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">ref='scrollView'</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">let scrollView = this.refs.scrollView</span><br><span class="line">let scrollView = this.refs['scrollView']</span><br></pre></td></tr></table></figure>
<ul>
<li>可以通过ref访问组件的属性和方法</li>
</ul>
<h4 id="ES6-定时器"><a href="#ES6-定时器" class="headerlink" title="ES6 定时器"></a>ES6 定时器</h4><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><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></pre></td><td class="code"><pre><span class="line">let scrollView = this.refs.scrollView;</span><br><span class="line">// 2.4timer 定时器的写法</span><br><span class="line">this.timer = setInterval(</span><br><span class="line"> ()=>{</span><br><span class="line"> var tempPage = 0;</span><br><span class="line"> // 修改banner索引</span><br><span class="line"> if ((this.state.currentPage+1) >= ImageData.data.length) {</span><br><span class="line"> tempPage = 0;</span><br><span class="line"> } else {</span><br><span class="line"> tempPage = this.state.currentPage+1;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> // 更新状态</span><br><span class="line"> this.setState({</span><br><span class="line"> currentPage: tempPage</span><br><span class="line"> })</span><br><span class="line"></span><br><span class="line"> let offSet_x = width * tempPage</span><br><span class="line"> scrollView.scrollResponderScrollTo({x:offSet_x, y:0, animated: true})</span><br><span class="line"> },</span><br><span class="line"> this.state.duration</span><br><span class="line">);</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></pre></td><td class="code"><pre><span class="line">this.timer && clearInterval(this.timer)</span><br></pre></td></tr></table></figure>
</div>
<footer class="article-footer">
<a data-url="https://github.com/aTreey/2018/07/26/ReactNative中ref使用/" data-id="cjlgmf6nb000tbbfwx69ulk28" class="article-share-link">Teilen</a>
</footer>
</div>
</article>
<article id="post-ES6语法" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2018/07/26/ES6语法/" class="article-date">
<time datetime="2018-07-26T15:05:32.639Z" itemprop="datePublished">2018-07-26</time>
</a>
</div>
<div class="article-inner">
<div class="article-entry" itemprop="articleBody">
<h1 id="JS-ES6-语法"><a href="#JS-ES6-语法" class="headerlink" title="JS ES6 语法"></a>JS ES6 语法</h1><h3 id="1-let-var-变量,作用域"><a href="#1-let-var-变量,作用域" class="headerlink" title="1. let var 变量,作用域"></a>1. let var 变量,作用域</h3><pre><code>var a = 10;
if (a > 10) {
let b = 5; // let 只能在代码块内被访问
console.log(b);
}
// 访问 b 报错
console.log(b);
console.log(a);
</code></pre><h3 id="2-const-只能分配一次值"><a href="#2-const-只能分配一次值" class="headerlink" title="2. const 只能分配一次值"></a>2. const 只能分配一次值</h3><p>{<br> const const_a = 1;<br> console.log(const_a)</p>
<pre><code>// 报错
const_a = 2;
// 声明一个常量数组
const const_array = [];
const_array.push(1);
const_array.push(2);
// 再次赋值时会报错
const_array = [3];
</code></pre><p>}</p>
<h3 id="3-解构语法"><a href="#3-解构语法" class="headerlink" title="3. 解构语法"></a>3. 解构语法</h3><p>{<br> // 1.解构数组<br> function getArray() {<br> return [10, 20, 30];<br> }</p>
<pre><code>let [a,b,c] = getArray()
console.log(a, b, c)
// 函数返回一个对象
function getObj() {
return {dessert: '面包', drink: '水', play: 'Game'};
}
// 2.解构对象
let {des: dessert, dri: drink, pla: play} = getObj()
console.log(des, dri, pla);
</code></pre><p>}</p>
<h3 id="4-模版字符串"><a href="#4-模版字符串" class="headerlink" title="4. 模版字符串"></a>4. 模版字符串</h3><p>{<br> let name = ‘姓名:’, password = ‘密码:’<br> let str_4 = name + ‘李老师’ + ‘—-‘ + password + ‘北京太热。。。’<br> console.log(str_4)</p>
<pre><code>// 使用 `${}` 包裹会生成字符串
let str_41 = `${name}李老师----${password}北京太热`
console.log(str_41)
// 多行显示时直接回车换行
let str_42 = `${name}李老师
----
${password}北京太热`
console.log(str_42)
</code></pre><p>}</p>
<h3 id="5-带标签的模版字符串"><a href="#5-带标签的模版字符串" class="headerlink" title="5. 带标签的模版字符串"></a>5. 带标签的模版字符串</h3><p>{<br> let name = ‘姓名:’, password = ‘密码:’<br> // 多行显示时直接回车换行<br> let str_5 = strTest<code>${name}李老师 ---- ${password}北京太热</code><br> console.log(str_5)</p>
<pre><code>// strings 字符中包含的被插值分割的子字符串已数组形式展现
// values 字符串中的插值数组
function strTest(strings, ...values) {
console.log(strings)
console.log(values)
}
function strTest1(strings, ...values) {
let result = '';
for (let i = 0; i < values.length; i++) {
result += strings[i]
result += values[i]
}
return result
}
</code></pre><p>}</p>
<h3 id="6-判断字符串是否包含其他字符"><a href="#6-判断字符串是否包含其他字符" class="headerlink" title="6. 判断字符串是否包含其他字符"></a>6. 判断字符串是否包含其他字符</h3><p>{<br> let name = ‘姓名:’, password = ‘密码:’<br> let str_6 = <code>${name}李老师---${password}北京真热</code><br> console.log(str_6.startsWith(<code>${name}</code>))<br> console.log(str_6.endsWith(<code>${name}</code>))<br> console.log(str_6.includes(‘李老师’))<br>}</p>
<h3 id="7-函数默认参数"><a href="#7-函数默认参数" class="headerlink" title="7. 函数默认参数"></a>7. 函数默认参数</h3><p>{<br> function funcDefaultParame(param1 = ‘a’, param2 = ‘b’, param3 = ‘c’) {<br> return <code>${param1}--${param2}--${param3}</code><br> }<br> console.log(funcDefaultParame(1, 2,3))<br>}</p>
<h3 id="8-“…”展开操作符"><a href="#8-“…”展开操作符" class="headerlink" title="8. “…”展开操作符"></a>8. “…”展开操作符</h3><p>{<br> let a = [1,2,3];<br> console.log(a);<br> console.log(…a)</p>
<pre><code>let b = [...a, 4, 5];
console.log(a);
console.log(b)
</code></pre><p>}</p>
<h3 id="9-‘…-‘剩余操作符-一般用在函数参数,-可以看作是一个可以展开的参数"><a href="#9-‘…-‘剩余操作符-一般用在函数参数,-可以看作是一个可以展开的参数" class="headerlink" title="9. ‘… ‘剩余操作符, 一般用在函数参数, 可以看作是一个可以展开的参数"></a>9. ‘… ‘剩余操作符, 一般用在函数参数, 可以看作是一个可以展开的参数</h3><pre><code>// ... param3表示函数可以接收除了param1, param2,两个参数外,多个参数,都会放在param3中
function operator(param1, param2, ...param3) {
console.log(param1, param2, param3)
}
operator('a','b','c','d','e','f','g')
</code></pre><h3 id="10-解构对象解构函数"><a href="#10-解构对象解构函数" class="headerlink" title="10. 解构对象解构函数"></a>10. 解构对象解构函数</h3><pre><code>// 当函数参数是对象是可以按照对象解构
function getObjcValue(param1, param2, {value1, value2} = {}) {
console.log(param1, param2, value1, value2)
}
getObjcValue(1,2,{value1: -3,value2: -4})
</code></pre><h3 id="11-获取函数名称"><a href="#11-获取函数名称" class="headerlink" title="11. 获取函数名称"></a>11. 获取函数名称</h3><pre><code>function getObjcValue(param1, param2, {value1, value2} = {}) {
console.log(param1, param2, value1, value2)
}
console.log(getObjcValue.name)
let funName = function getfunctionName() { }
console.log(funName.name)
</code></pre><h3 id="12-箭头函数"><a href="#12-箭头函数" class="headerlink" title="12. 箭头函数"></a>12. 箭头函数</h3><pre><code>// 原来普通写法
var funType = function arrowfunction(param) {
return param
}
// 函数参数 => 函数返回值
// '=>' 的左边表示箭头函数的参数,多个时表示为 (param1, param2, param3)
// '=>' 的右边表示箭头函数的返回值,如果返回值是一个对象时用 { } 表示
let arrowFunction = (param1, param2) => {
return `${param1}${param2}`
</code></pre><p>}</p>
<h3 id="13"><a href="#13" class="headerlink" title="13"></a>13</h3>
</div>
<footer class="article-footer">
<a data-url="https://github.com/aTreey/2018/07/26/ES6语法/" data-id="cjlgmf6n3000jbbfwace9cxxl" class="article-share-link">Teilen</a>
</footer>
</div>
</article>
<article id="post-Swift 协议使用" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2018/07/19/Swift 协议使用/" class="article-date">
<time datetime="2018-07-19T15:32:44.287Z" itemprop="datePublished">2018-07-19</time>
</a>
</div>
<div class="article-inner">
<div class="article-entry" itemprop="articleBody">
<h1 id="Swift-协议使用"><a href="#Swift-协议使用" class="headerlink" title="Swift 协议使用"></a>Swift 协议使用</h1><h2 id="对UIView-扩展"><a href="#对UIView-扩展" class="headerlink" title="对UIView 扩展"></a>对UIView 扩展</h2><h3 id="按钮-文本框抖动动画"><a href="#按钮-文本框抖动动画" class="headerlink" title="按钮/文本框抖动动画"></a>按钮/文本框抖动动画</h3><ul>
<li><p>声明协议</p>
<ul>
<li><p>协议中定义属性:遵循该协议的类型都具有此属性</p>
<ul>
<li>必须明确规定该属性是可读的 <code>{get}</code> 或者可写的 <code>{set}</code>,或是可读可写的 <code>{get set}</code></li>
<li>使用static修饰声明一个类类型属性</li>
</ul>
</li>
<li><p>协议中定义方法</p>
</li>
</ul>
</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></pre></td><td class="code"><pre><span class="line">protocol Shakable {}</span><br><span class="line">extension Shakable where Self: UIView {</span><br><span class="line"> func shakeAnimation() {</span><br><span class="line"> let animation = CABasicAnimation(keyPath: "position")</span><br><span class="line"> animation.duration = 0.08</span><br><span class="line"> animation.repeatCount = 5</span><br><span class="line"> animation.autoreverses = true</span><br><span class="line"> animation.fromValue = NSValue(cgPoint: CGPoint(x: self.center.x - 4, y: self.center.y))</span><br><span class="line"> animation.toValue = NSValue(cgPoint: CGPoint(x: self.center.x + 4, y: self.center.y))</span><br><span class="line"> layer.add(animation, forKey: "position")</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<ul>
<li>自定义UI控件并遵守协议</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">class MyButton: UIButton, Shakable { }</span><br><span class="line">class MySwitch: UISwitch, Shakable { }</span><br><span class="line">class MyTextField: UITextField, Shakable { }</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><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">let mySwitch = MySwitch()</span><br><span class="line">mySwitch.isOn = true</span><br><span class="line">self.mySwitch = mySwitch</span><br><span class="line">view.addSubview(mySwitch)</span><br><span class="line">mySwitch.translatesAutoresizingMaskIntoConstraints = false</span><br><span class="line">mySwitch.topAnchor.constraint(equalTo: view.bottomAnchor, constant: 10).isActive = true</span><br><span class="line">mySwitch.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10).isActive = true</span><br><span class="line"></span><br><span class="line">// 调用</span><br><span class="line">mySwitch.shakeAnimation()</span><br></pre></td></tr></table></figure>
<h2 id="UITableViewCell使用"><a href="#UITableViewCell使用" class="headerlink" title="UITableViewCell使用"></a>UITableViewCell使用</h2><h3 id="定义协议"><a href="#定义协议" class="headerlink" title="定义协议"></a>定义协议</h3><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></pre></td><td class="code"><pre><span class="line">protocol ReusableView: class { }</span><br><span class="line"></span><br><span class="line">extension ReusableView where Self: UIView {</span><br><span class="line"> static var reuseIdentifier: String {</span><br><span class="line"> return String(describing: self)</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><span class="line">### 对tableView扩展</span><br></pre></td></tr></table></figure>
<p>extension UITableView {<br> /// 注册cell<br> func register<T: UITableViewCell>(T: T.Type) where T: ReusableView {<br> print(T.reuseIdentifier)<br> self.register(T.self, forCellReuseIdentifier: T.reuseIdentifier)<br> }</p>
<pre><code>/// 调用cell
func dequeueReusableCell<T: UITableViewCell>(_ indexPath: IndexPath) -> T where T: ReusableView {
print(T.reuseIdentifier)
return self.dequeueReusableCell(withIdentifier: T.reuseIdentifier, for: indexPath) as! T
}
</code></pre><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></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">### 用法</span><br><span class="line"></span><br><span class="line">- 创建自定义的cell,需要遵守协议</span><br></pre></td></tr></table></figure></p>
<p>class TableProtocolCell: UITableViewCell, ReusableView {<br> override var reuseIdentifier: String? {<br> return “cell”<br> }<br> override init(style: UITableViewCellStyle, reuseIdentifier: String?) {<br> super.init(style: style, reuseIdentifier: reuseIdentifier)<br> self.backgroundColor = .cyan<br> self.textLabel?.text = “通过协议和泛型创建的cell”<br> self.textLabel?.textColor = .blue<br> }<br> required init?(coder aDecoder: NSCoder) {<br> fatalError(“init(coder:) has not been implemented”)<br> }<br>}</p>
<p>class TableProtocolCell2: UITableViewCell, ReusableView {<br> override init(style: UITableViewCellStyle, reuseIdentifier: String?) {<br> super.init(style: style, reuseIdentifier: reuseIdentifier)<br> self.backgroundColor = .red<br> self.textLabel?.text = “cell1 - 通过协议和泛型创建的”<br> self.textLabel?.textAlignment = .right<br> }<br> required init?(coder aDecoder: NSCoder) {<br> fatalError(“init(coder:) has not been implemented”)<br> }<br>}<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">- 注册和使用</span><br></pre></td></tr></table></figure></p>
<p>class TableViewProtocolController: UITableViewController {<br> override func viewDidLoad() {<br> super.viewDidLoad()<br> tableView.register(T: TableProtocolCell.self)<br> tableView.register(T: TableProtocolCell2.self)<br> }</p>
<pre><code>override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = UITableViewCell()
if indexPath.row % 2 == 0 {
cell = tableView.dequeueReusableCell(indexPath) as TableProtocolCell
} else {
cell = tableView.dequeueReusableCell(indexPath) as TableProtocolCell2
}
return cell
}
</code></pre><p>}</p>
<p><code>`</code></p>
</div>
<footer class="article-footer">
<a data-url="https://github.com/aTreey/2018/07/19/Swift 协议使用/" data-id="cjlgmf6nd000zbbfwacsyt8g5" class="article-share-link">Teilen</a>
</footer>
</div>
</article>
<article id="post-Swift泛型" class="article article-type-post" itemscope itemprop="blogPost">
<div class="article-meta">
<a href="/2018/07/19/Swift泛型/" class="article-date">
<time datetime="2018-07-19T14:33:38.827Z" itemprop="datePublished">2018-07-19</time>
</a>
</div>
<div class="article-inner">
<div class="article-entry" itemprop="articleBody">
<h2 id="Swift-泛型"><a href="#Swift-泛型" class="headerlink" title="Swift 泛型"></a>Swift 泛型</h2><h3 id="泛型定义–wikipedia"><a href="#泛型定义–wikipedia" class="headerlink" title="泛型定义–wikipedia"></a>泛型定义–<code>wikipedia</code></h3><ol>
<li>在程序编码中一些包含类型参数的类型,也就是说泛型的参数只可以代表类,不能代表个别对象。(这是当今较常见的定义)</li>
<li>在程序编码中一些包含参数的类。其参数可以代表类或对象等等。(现在人们大多把这称作模板)</li>
</ol>
<h3 id="泛型的用处"><a href="#泛型的用处" class="headerlink" title="泛型的用处"></a>泛型的用处</h3><p>泛型可以实现传入一个指定类型后做一些操作然后返回后还是原来指定的类型,你可以指定特定的类型(特定是指约束)</p>
<h3 id="泛型和-Any-的区别"><a href="#泛型和-Any-的区别" class="headerlink" title="泛型和 Any 的区别"></a>泛型和 <code>Any</code> 的区别</h3><p>区别:<code>Any</code>能代表任何类型,但是不能返回某个具体的类型,都需要使用 as 去转化,而泛型正好相反</p>
<ul>
<li>Any 可以代表任何类型,除了class之外还可以代表struct,enum,</li>
<li><code>AnyObject</code> 可以代码任何 <code>class</code> 的类型, swift 中基本类型, <code>Array</code> 和 <code>Dictionary</code> 都是 <code>struct</code> 类型,都不能使用 <code>AnyObject</code> 来接受</li>
</ul>
<p><a href="http://swifter.tips/any-anyobject/" target="_blank" rel="noopener">Swift中Any 和 AnyObject用法</a></p>
<h3 id="泛型函数和泛型参数"><a href="#泛型函数和泛型参数" class="headerlink" title="泛型函数和泛型参数"></a>泛型函数和泛型参数</h3><p><code>swapTwoValues</code>是一个泛型函数,可以接收或者返回任何类型</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">func swapTwoValues<T>(inout a: T, inout b: T) {</span><br><span class="line"> let temporaryA = a</span><br><span class="line"> a = b</span><br><span class="line"> b = temporaryA</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<ul>
<li><p><code>swapTwoValues</code> 函数名后面的 <code><T></code> 表示这个 <code>T</code> 类型是函数所定义的一个类型, <code>T</code> 只是一个类型的占位符,不用关心具体类型</p>
</li>
<li><p><code>(inout a: T, inout b: T)</code> 中a和b两个参数类型<code>T</code>是泛型参数</p>
</li>
</ul>
<h3 id="类型约束"><a href="#类型约束" class="headerlink" title="类型约束"></a>类型约束</h3><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">func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {</span><br><span class="line"> // function body goes here</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<ul>
<li>泛型参数<code>T</code>约束条件:必须是<code>SomeClass</code>类的子类</li>
<li>泛型参数<code>U</code>约束条件:必须遵守<code>SomeProtocol</code>协议</li>
<li>使用where指定约束</li>
</ul>
</div>
<footer class="article-footer">
<a data-url="https://github.com/aTreey/2018/07/19/Swift泛型/" data-id="cjlgmf6no001ibbfwqdd9pdnf" class="article-share-link">Teilen</a>
</footer>
</div>
</article>
<nav id="page-nav">
<span class="page-number current">1</span><a class="page-number" href="/page/2/">2</a><a class="page-number" href="/page/3/">3</a><span class="space">…</span><a class="page-number" href="/page/5/">5</a><a class="extend next" rel="next" href="/page/2/">weiter »</a>
</nav>
</section>
<aside id="sidebar">
<div class="widget-wrap">
<h3 class="widget-title">Tags</h3>
<div class="widget">
<ul class="tag-list"><li class="tag-list-item"><a class="tag-list-link" href="/tags/AES-Base64-MD5/">AES, Base64, MD5</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Alamofire/">Alamofire</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/AlertView/">AlertView</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/GCD/">GCD</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Hexo/">Hexo</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/OC-JS/">OC, JS</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Quartz-2D/">Quartz 2D</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Quartz2D/">Quartz2D</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/RunTime/">RunTime</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/SDWebImage/">SDWebImage</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/SQL/">SQL</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Swift/">Swift</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/TableView/">TableView</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/WKWebView/">WKWebView</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/git/">git</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/swift/">swift</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/异步/">异步</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/本地缓存/">本地缓存</a></li></ul>
</div>
</div>
<div class="widget-wrap">
<h3 class="widget-title">Tag Cloud</h3>
<div class="widget tagcloud">
<a href="/tags/AES-Base64-MD5/" style="font-size: 10px;">AES, Base64, MD5</a> <a href="/tags/Alamofire/" style="font-size: 10px;">Alamofire</a> <a href="/tags/AlertView/" style="font-size: 10px;">AlertView</a> <a href="/tags/GCD/" style="font-size: 10px;">GCD</a> <a href="/tags/Hexo/" style="font-size: 10px;">Hexo</a> <a href="/tags/OC-JS/" style="font-size: 10px;">OC, JS</a> <a href="/tags/Quartz-2D/" style="font-size: 10px;">Quartz 2D</a> <a href="/tags/Quartz2D/" style="font-size: 15px;">Quartz2D</a> <a href="/tags/RunTime/" style="font-size: 10px;">RunTime</a> <a href="/tags/SDWebImage/" style="font-size: 10px;">SDWebImage</a> <a href="/tags/SQL/" style="font-size: 10px;">SQL</a> <a href="/tags/Swift/" style="font-size: 10px;">Swift</a> <a href="/tags/TableView/" style="font-size: 10px;">TableView</a> <a href="/tags/WKWebView/" style="font-size: 20px;">WKWebView</a> <a href="/tags/git/" style="font-size: 10px;">git</a> <a href="/tags/swift/" style="font-size: 15px;">swift</a> <a href="/tags/异步/" style="font-size: 10px;">异步</a> <a href="/tags/本地缓存/" style="font-size: 10px;">本地缓存</a>
</div>
</div>
<div class="widget-wrap">
<h3 class="widget-title">Archiv</h3>
<div class="widget">
<ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/08/">August 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/07/">July 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/06/">June 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/03/">March 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/02/">February 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/01/">January 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/12/">December 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/11/">November 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/04/">April 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/03/">March 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/02/">February 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/01/">January 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/12/">December 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/11/">November 2016</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/10/">October 2016</a></li></ul>
</div>
</div>
<div class="widget-wrap">
<h3 class="widget-title">letzter Beitrag</h3>
<div class="widget">
<ul>
<li>
<a href="/2018/08/30/Swift错误处理/">(no title)</a>
</li>
<li>
<a href="/2018/08/25/Swift协议别名/">(no title)</a>
</li>
<li>
<a href="/2018/08/25/Swift协议扩展/">(no title)</a>
</li>
<li>
<a href="/2018/08/25/Swift下标和运算符重载/">(no title)</a>
</li>
<li>
<a href="/2018/08/22/iOS通过URL获取HTML中标题/">(no title)</a>
</li>
</ul>
</div>
</div>
</aside>
</div>
<footer id="footer">
<div class="outer">
<div id="footer-info" class="inner">
© 2018 aTreey<br>
Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
</div>
</div>
</footer>
</div>
<nav id="mobile-nav">
<a href="/" class="mobile-nav-link">Home</a>
<a href="/archives" class="mobile-nav-link">Archives</a>
</nav>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
<script src="/fancybox/jquery.fancybox.pack.js"></script>
<script src="/js/script.js"></script>
</div>
</body>
</html>