-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
2017 lines (834 loc) · 114 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html class="theme-next muse use-motion" lang="">
<head>
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">
<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
<link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />
<link href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />
<link href="/css/main.css?v=5.1.2" rel="stylesheet" type="text/css" />
<meta name="keywords" content="Hexo, NexT" />
<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico?v=5.1.2" />
<meta name="description" content="an iOS And Mac OS dev">
<meta property="og:type" content="website">
<meta property="og:title" content="Hack'Blog">
<meta property="og:url" content="http://yoursite.com/index.html">
<meta property="og:site_name" content="Hack'Blog">
<meta property="og:description" content="an iOS And Mac OS dev">
<meta property="og:locale" content="default">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Hack'Blog">
<meta name="twitter:description" content="an iOS And Mac OS dev">
<script type="text/javascript" id="hexo.configurations">
var NexT = window.NexT || {};
var CONFIG = {
root: '/',
scheme: 'Muse',
sidebar: {"position":"left","display":"post","offset":12,"offset_float":12,"b2t":false,"scrollpercent":false,"onmobile":false},
fancybox: true,
tabs: true,
motion: true,
duoshuo: {
userId: '0',
author: 'Author'
},
algolia: {
applicationID: '',
apiKey: '',
indexName: '',
hits: {"per_page":10},
labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
}
};
</script>
<link rel="canonical" href="http://yoursite.com/"/>
<title>Hack'Blog</title>
</head>
<body itemscope itemtype="http://schema.org/WebPage" lang="default">
<div class="container sidebar-position-left
page-home
">
<div class="headband"></div>
<header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
<div class="header-inner"><div class="site-brand-wrapper">
<div class="site-meta ">
<div class="custom-logo-site-title">
<a href="/" class="brand" rel="start">
<span class="logo-line-before"><i></i></span>
<span class="site-title">Hack'Blog</span>
<span class="logo-line-after"><i></i></span>
</a>
</div>
<p class="site-subtitle">iOS And Mac OS dev</p>
</div>
<div class="site-nav-toggle">
<button>
<span class="btn-bar"></span>
<span class="btn-bar"></span>
<span class="btn-bar"></span>
</button>
</div>
</div>
<nav class="site-nav">
<ul id="menu" class="menu">
<li class="menu-item menu-item-home">
<a href="/" rel="section">
<i class="menu-item-icon fa fa-fw fa-home"></i> <br />
Home
</a>
</li>
<li class="menu-item menu-item-archives">
<a href="/archives/" rel="section">
<i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
Archives
</a>
</li>
<li class="menu-item menu-item-tags">
<a href="/tags/" rel="section">
<i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
Tags
</a>
</li>
</ul>
</nav>
</div>
</header>
<main id="main" class="main">
<div class="main-inner">
<div class="content-wrap">
<div id="content" class="content">
<section id="posts" class="posts-expand">
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/03/25/const-static-extern简介/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Hack">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.gif">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Hack'Blog">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2019/03/25/const-static-extern简介/" itemprop="url">const,static,extern简介</a></h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Post created" itemprop="dateCreated datePublished" datetime="2019-03-25T13:47:14+08:00">
2019-03-25
</time>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>#const与宏的区别(面试题):</p>
<ul>
<li>const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量。<ul>
<li>编译时刻:宏是预编译(编译之前处理),const是编译阶段。</li>
<li>编译检查:宏不做检查,不会报编译错误,只是替换,const会编译检查,会报编译错误。</li>
<li>宏的好处:宏能定义一些函数,方法。 const不能。</li>
<li>宏的坏处:使用大量宏,容易造成编译时间久,每次都需要重新替换。<br>注意:很多Blog都说使用宏,会消耗很多内存,我这验证并不会生成很多内存,宏定义的是常量,常量都放在常量区,只会生成一份内存。 </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><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">#define XMGAccount @"account"</span><br><span class="line"></span><br><span class="line">#define XMGUserDefault [NSUserDefaults standardUserDefaults]</span><br><span class="line"></span><br><span class="line">// 字符串常量</span><br><span class="line">static NSString * const account = @"account";</span><br><span class="line"></span><br><span class="line">- (void)viewDidLoad {</span><br><span class="line"> [super viewDidLoad];</span><br><span class="line"></span><br><span class="line"> // 偏好设置存储</span><br><span class="line"> // 使用宏</span><br><span class="line"> [XMGUserDefault setValue:@"123" forKey:XMGAccount];</span><br><span class="line"></span><br><span class="line"> // 使用const常量</span><br><span class="line"> [[NSUserDefaults standardUserDefaults] setValue:@"123" forKey:account];</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>#const作用:限制类型</p>
<ul>
<li>1.const仅仅用来修饰右边的变量(基本数据变量p,指针变量*p)</li>
<li><p>2.被const修饰的变量是只读的。</p>
</li>
<li><p>const基本使用</p>
</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><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></pre></td><td class="code"><pre><span class="line">- (void)viewDidLoad {</span><br><span class="line"> [super viewDidLoad];</span><br><span class="line"></span><br><span class="line"> // 定义变量</span><br><span class="line"> int a = 1;</span><br><span class="line"></span><br><span class="line"> // 允许修改值</span><br><span class="line"> a = 20;</span><br><span class="line"></span><br><span class="line"> // const两种用法</span><br><span class="line"> // const:修饰基本变量p</span><br><span class="line"> // 这两种写法是一样的,const只修饰右边的基本变量b</span><br><span class="line"> const int b = 20; // b:只读变量</span><br><span class="line"> int const b = 20; // b:只读变量</span><br><span class="line"></span><br><span class="line"> // 不允许修改值</span><br><span class="line"> b = 1;</span><br><span class="line"></span><br><span class="line"> // const:修饰指针变量*p,带*的变量,就是指针变量.</span><br><span class="line"> // 定义一个指向int类型的指针变量,指向a的地址</span><br><span class="line"> int *p = &a;</span><br><span class="line"></span><br><span class="line"> int c = 10;</span><br><span class="line"></span><br><span class="line"> p = &c;</span><br><span class="line"></span><br><span class="line"> // 允许修改p指向的地址,</span><br><span class="line"> // 允许修改p访问内存空间的值</span><br><span class="line"> *p = 20;</span><br><span class="line"></span><br><span class="line"> // const修饰指针变量访问的内存空间,修饰的是右边*p1,</span><br><span class="line"> // 两种方式一样</span><br><span class="line"> const int *p1; // *p1:常量 p1:变量</span><br><span class="line"> int const *p1; // *p1:常量 p1:变量</span><br><span class="line"></span><br><span class="line"> // const修饰指针变量p1</span><br><span class="line"> int * const p1; // *p1:变量 p1:常量</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> // 第一个const修饰*p1 第二个const修饰 p1</span><br><span class="line"> // 两种方式一样</span><br><span class="line"> const int * const p1; // *p1:常量 p1:常量</span><br><span class="line"></span><br><span class="line"> int const * const p1; // *p1:常量 p1:常量</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h1 id="const开发中使用场景"><a href="#const开发中使用场景" class="headerlink" title="const开发中使用场景:"></a>const开发中使用场景:</h1><ul>
<li>1.当一个方法参数只读</li>
<li>2.定义只读全局变量</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></pre></td><td class="code"><pre><span class="line">@implementation ViewController</span><br><span class="line"></span><br><span class="line">// 定义只读全局常量</span><br><span class="line">NSString * const str = @"123";</span><br><span class="line"></span><br><span class="line">// 当一个方法的参数,只读.</span><br><span class="line">- (void)test:(NSString * const)name</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">- (void)test1:(int const *)a{</span><br><span class="line"></span><br><span class="line">// *a = 10;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">// 基本数据类型只读</span><br><span class="line">- (void)test2:(int const)a{</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">@end</span><br></pre></td></tr></table></figure>
<h1 id="static和extern简单使用-要使用一个东西,先了解其作用"><a href="#static和extern简单使用-要使用一个东西,先了解其作用" class="headerlink" title="static和extern简单使用(要使用一个东西,先了解其作用)"></a>static和extern简单使用(要使用一个东西,先了解其作用)</h1><ul>
<li><p>static作用:</p>
<ul>
<li>修饰局部变量:</li>
</ul>
<ol>
<li><p>延长局部变量的生命周期,程序结束才会销毁。</p>
</li>
<li><p>局部变量只会生成一份内存,只会初始化一次。</p>
</li>
</ol>
<ul>
<li>修饰全局变量</li>
</ul>
<ol>
<li>只能在本文件中访问,修改全局变量的作用域,生命周期不会改</li>
</ol>
</li>
<li><p>extern作用:</p>
<ul>
<li>只是用来获取全局变量(包括全局静态变量)的值,不能用于定义变量</li>
</ul>
</li>
<li>extern工作原理:<ul>
<li>先在当前文件查找有没有全局变量,没有找到,才会去其他文件查找。</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><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">// 全局变量:只有一份内存,所有文件共享,与extern联合使用。</span><br><span class="line">int a = 20;</span><br><span class="line"></span><br><span class="line">// static修饰全局变量</span><br><span class="line">static int age = 20;</span><br><span class="line"></span><br><span class="line">- (void)test</span><br><span class="line">{</span><br><span class="line"> // static修饰局部变量</span><br><span class="line"> static int age = 0;</span><br><span class="line"> age++;</span><br><span class="line"> NSLog(@"%d",age);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">- (void)viewDidLoad {</span><br><span class="line"> [super viewDidLoad];</span><br><span class="line"> // Do any additional setup after loading the view, typically from a nib.</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> [self test];</span><br><span class="line"> [self test];</span><br><span class="line"></span><br><span class="line"> extern int age;</span><br><span class="line"> NSLog(@"%d",age);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h1 id="static与const联合使用"><a href="#static与const联合使用" class="headerlink" title="static与const联合使用"></a>static与const联合使用</h1><ul>
<li>static与const作用:声明一个只读的静态变量</li>
<li>开发使用场景:在一个文件中经常使用的字符串常量,可以使用static与const组合</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></pre></td><td class="code"><pre><span class="line">// 开发中常用static修饰全局变量,只改变作用域</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">static const int a = 20;</span><br><span class="line"></span><br><span class="line">// staic和const联合的作用:声明一个静态的全局只读常量</span><br><span class="line"></span><br><span class="line">// iOS中staic和const常用使用场景,是用来代替宏,把一个经常使用的字符串常量,定义成静态全局只读变量.</span><br><span class="line"></span><br><span class="line">// 开发中经常拿到key修改值,因此用const修饰key,表示key只读,不允许修改。</span><br><span class="line">static NSString * const key = @"name";</span><br><span class="line"></span><br><span class="line">// 如果 const修饰 *key1,表示*key1只读,key1还是能改变。</span><br><span class="line"></span><br><span class="line">static NSString const *key1 = @"name";</span><br></pre></td></tr></table></figure>
<h1 id="extern与const联合使用"><a href="#extern与const联合使用" class="headerlink" title="extern与const联合使用"></a>extern与const联合使用</h1><ul>
<li>开发中使用场景:在多个文件中经常使用的同一个字符串常量,可以使用extern与const组合。</li>
<li>原因:<ul>
<li>static与const组合:在每个文件都需要定义一份静态全局变量。</li>
<li>extern与const组合:只需要定义一份全局变量,多个文件共享。</li>
</ul>
</li>
<li>全局常量正规写法:开发中便于管理所有的全局变量,通常搞一个GlobeConst文件,里面专门定义全局变量,统一管理,要不然项目文件多不好找。</li>
</ul>
<ul>
<li>GlobeConst.h</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">/*******************************首页****************************/</span><br><span class="line"></span><br><span class="line">extern NSString * const nameKey = @"name";</span><br><span class="line"></span><br><span class="line">/*******************************首页****************************/</span><br><span class="line">GlobeConst.m</span><br><span class="line">#import <Foundation/Foundation.h></span><br><span class="line"></span><br><span class="line">/*******************************首页****************************/</span><br><span class="line"></span><br><span class="line">NSString * const nameKey = @"name";</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">/*******************************首页****************************/</span><br></pre></td></tr></table></figure>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</div>
</article>
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/03/25/iOS9新特性之关键字/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Hack">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.gif">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Hack'Blog">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2019/03/25/iOS9新特性之关键字/" itemprop="url">iOS9新特性之关键字</a></h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Post created" itemprop="dateCreated datePublished" datetime="2019-03-25T13:35:00+08:00">
2019-03-25
</time>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h2 id="iOS9新出的关键字-用来修饰属性-或者方法的参数-方法的返回值"><a href="#iOS9新出的关键字-用来修饰属性-或者方法的参数-方法的返回值" class="headerlink" title="iOS9新出的关键字:用来修饰属性,或者方法的参数,方法的返回值"></a>iOS9新出的关键字:用来修饰属性,或者方法的参数,方法的返回值</h2><ul>
<li><p>好处:</p>
<ul>
<li><p>迎合swift</p>
</li>
<li><p>提高我们开发人员开发规范,减少程序员之间交流</p>
</li>
</ul>
</li>
<li><p>注意:</p>
<ul>
<li>iOS9新出关键字<code>nonnull,nullable,null_resettable,_Null_unspecified</code>只能修饰对象,不能修饰基本数据类型. </li>
<li>nullable`作用:表示可以为空</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></pre></td><td class="code"><pre><span class="line">nullable书写规范:</span><br><span class="line">// 方式一:</span><br><span class="line">@property (nonatomic, strong, nullable) NSString *name;</span><br><span class="line">// 方式二:</span><br><span class="line">@property (nonatomic, strong) NSString *_Nullable name;</span><br><span class="line">// 方式三:</span><br><span class="line">@property (nonatomic, strong) NSString *__nullable name;</span><br></pre></td></tr></table></figure>
<ul>
<li><code>nonnull</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">nonnull: non:非 null:空</span><br><span class="line"></span><br><span class="line">书写格式:</span><br><span class="line"> @property (nonatomic, strong, nonnull) NSString *icon;</span><br><span class="line"></span><br><span class="line"> @property (nonatomic, strong) NSString * _Nonnull icon;</span><br><span class="line"></span><br><span class="line"> @property (nonatomic, strong) NSString * __nonnull icon;</span><br></pre></td></tr></table></figure>
<ul>
<li><p>在<code>NS_ASSUME_NONNULL_BEGIN</code>和<code>NS_ASSUME_NONNULL_END</code>之间,定义的所有对象属性和方法默认都是<code>nonnull</code></p>
</li>
<li><p><code>null_resettable</code>作用: get:不能返回为空, set可以为空</p>
</li>
</ul>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">// 书写方式:</span><br><span class="line">@property (nonatomic, strong, null_resettable) NSString *name;</span><br><span class="line"></span><br><span class="line"> // 注意;如果使用null_resettable,必须 重写get方法或者set方法,处理传递的值为空的情况</span><br></pre></td></tr></table></figure>
<ul>
<li><code>_Null_unspecified:</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></pre></td><td class="code"><pre><span class="line">书写方式只有这种</span><br><span class="line"> 方式一</span><br><span class="line"> @property (nonatomic, strong) NSString *_Null_unspecified name;</span><br><span class="line"> 方式二</span><br><span class="line"> @property (nonatomic, strong) NSString *__null_unspecified name;</span><br></pre></td></tr></table></figure>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</div>
</article>
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/03/25/runtime学习/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Hack">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.gif">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Hack'Blog">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2019/03/25/runtime学习/" itemprop="url">Runtime学习</a></h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Post created" itemprop="dateCreated datePublished" datetime="2019-03-25T09:26:09+08:00">
2019-03-25
</time>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h2 id="Runtime简介"><a href="#Runtime简介" class="headerlink" title="Runtime简介"></a>Runtime简介</h2><ul>
<li>RunTime简称运行时。OC就是<code>运行时机制</code>,也就是在运行时候的一些机制,其中最主要的是消息机制。</li>
<li>对于C语言,<code>函数的调用在编译的时候会决定调用哪个函数。</code><br>对于OC的函数,属于动态调用过程,在编译的时候并不能决定真正调用哪个函数,只有在真正运行的时候才会根据函数的名称找到对应的函数来调用。</li>
<li>事实证明:<ul>
<li>在编译阶段,OC可以<code>调用任何函数</code>,即使这个函数并未实现,只要声明过就不会报错。</li>
<li>在编译阶段,C语言调用<code>未实现的函数</code>就会报错。</li>
</ul>
</li>
</ul>
<h2 id="Runtime作用"><a href="#Runtime作用" class="headerlink" title="Runtime作用"></a>Runtime作用</h2><h3 id="发送消息"><a href="#发送消息" class="headerlink" title="发送消息"></a>发送消息</h3><ul>
<li>方法调用的本质,就是让对象发送消息。</li>
<li>objc_msgSend,只有对象才能发送消息,因此以objc开头.</li>
<li>使用消息机制前提,必须导入#import <objc/message.h></li>
<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></pre></td><td class="code"><pre><span class="line">// 创建person对象</span><br><span class="line"> Person *p = [[Person alloc] init];</span><br><span class="line"></span><br><span class="line"> // 调用对象方法</span><br><span class="line"> [p eat];</span><br><span class="line"></span><br><span class="line"> // 本质:让对象发送消息</span><br><span class="line"> objc_msgSend(p, @selector(eat));</span><br><span class="line"></span><br><span class="line"> // 调用类方法的方式:两种</span><br><span class="line"> // 第一种通过类名调用</span><br><span class="line"> [Person eat];</span><br><span class="line"> // 第二种通过类对象调用</span><br><span class="line"> [[Person class] eat];</span><br><span class="line"></span><br><span class="line"> // 用类名调用类方法,底层会自动把类名转换成类对象调用</span><br><span class="line"> // 本质:让类对象发送消息</span><br><span class="line"> objc_msgSend([Person class], @selector(eat));</span><br></pre></td></tr></table></figure>
<ul>
<li>消息机制原理:对象根据方法编号SEL去映射表查找对应的方法实现</li>
</ul>
<p><img src="/2019/03/25/runtime学习/Snip20151013_4.png" alt=""></p>
<h3 id="交换方法"><a href="#交换方法" class="headerlink" title="交换方法"></a>交换方法</h3><ul>
<li>开发使用场景:系统自带的方法功能不够,给系统自带的方法扩展一些功能,并且保持原有的功能。</li>
<li>方式一:继承系统的类,重写方法. </li>
<li>方式二:使用runtime,交换方法.</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></pre></td><td class="code"><pre><span class="line">@implementation ViewController</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">- (void)viewDidLoad {</span><br><span class="line"> [super viewDidLoad];</span><br><span class="line"> // Do any additional setup after loading the view, typically from a nib.</span><br><span class="line"> // 需求:给imageNamed方法提供功能,每次加载图片就判断下图片是否加载成功。</span><br><span class="line"> // 步骤一:先搞个分类,定义一个能加载图片并且能打印的方法+ (instancetype)imageWithName:(NSString *)name;</span><br><span class="line"> // 步骤二:交换imageNamed和imageWithName的实现,就能调用imageWithName,间接调用imageWithName的实现。</span><br><span class="line"> UIImage *image = [UIImage imageNamed:@"123"];</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">@end</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">@implementation UIImage (Image)</span><br><span class="line">// 加载分类到内存的时候调用</span><br><span class="line">+ (void)load</span><br><span class="line">{</span><br><span class="line"> // 交换方法</span><br><span class="line"></span><br><span class="line"> // 获取imageWithName方法地址</span><br><span class="line"> Method imageWithName = class_getClassMethod(self, @selector(imageWithName:));</span><br><span class="line"></span><br><span class="line"> // 获取imageWithName方法地址</span><br><span class="line"> Method imageName = class_getClassMethod(self, @selector(imageNamed:));</span><br><span class="line"></span><br><span class="line"> // 交换方法地址,相当于交换实现方式</span><br><span class="line"> method_exchangeImplementations(imageWithName, imageName);</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">// 不能在分类中重写系统方法imageNamed,因为会把系统的功能给覆盖掉,而且分类中不能调用super.</span><br><span class="line"></span><br><span class="line">// 既能加载图片又能打印</span><br><span class="line">+ (instancetype)imageWithName:(NSString *)name</span><br><span class="line">{</span><br><span class="line"></span><br><span class="line"> // 这里调用imageWithName,相当于调用imageName</span><br><span class="line"> UIImage *image = [self imageWithName:name];</span><br><span class="line"></span><br><span class="line"> if (image == nil) {</span><br><span class="line"> NSLog(@"加载空的图片");</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> return image;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">@end</span><br></pre></td></tr></table></figure>
<ul>
<li>交换原理</li>
</ul>
<p><img src="/2019/03/25/runtime学习/Snip20151013_2.png" alt="交换之前" title="交换之前"></p>
<p><img src="/2019/03/25/runtime学习/Snip20151013_3.png" alt="交换之后" title="交换之后"></p>
<h3 id="动态添加方法"><a href="#动态添加方法" class="headerlink" title="动态添加方法"></a>动态添加方法</h3><ul>
<li>开发使用场景:如果一个类方法非常多,加载类到内存的时候也比较耗费资源,需要给每个方法生成映射表,可以使用动态给某个类,添加方法解决。</li>
<li>经典面试题:有没有使用performSelector,其实主要想问你有没有动态添加过方法。</li>
<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><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></pre></td><td class="code"><pre><span class="line">@implementation ViewController</span><br><span class="line"></span><br><span class="line">- (void)viewDidLoad {</span><br><span class="line"> [super viewDidLoad];</span><br><span class="line"> // Do any additional setup after loading the view, typically from a nib.</span><br><span class="line"></span><br><span class="line"> Person *p = [[Person alloc] init];</span><br><span class="line"></span><br><span class="line"> // 默认person,没有实现eat方法,可以通过performSelector调用,但是会报错。</span><br><span class="line"> // 动态添加方法就不会报错</span><br><span class="line"> [p performSelector:@selector(eat)];</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">@end</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">@implementation Person</span><br><span class="line">// void(*)()</span><br><span class="line">// 默认方法都有两个隐式参数,</span><br><span class="line">void eat(id self,SEL sel)</span><br><span class="line">{</span><br><span class="line"> NSLog(@"%@ %@",self,NSStringFromSelector(sel));</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">+ (BOOL)resolveInstanceMethod:(SEL)sel</span><br><span class="line">{</span><br><span class="line"></span><br><span class="line"> if (sel == @selector(eat)) {</span><br><span class="line"> // 动态添加eat方法</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"> // 第四个参数:函数的类型,(返回值+参数类型) v:void @:对象->self :表示SEL->_cmd</span><br><span class="line"> class_addMethod(self, @selector(eat), eat, "v@:");</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> return [super resolveInstanceMethod:sel];</span><br><span class="line">}</span><br><span class="line">@end</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><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line">@implementation ViewController</span><br><span class="line"></span><br><span class="line">- (void)viewDidLoad {</span><br><span class="line"> [super viewDidLoad];</span><br><span class="line"> // Do any additional setup after loading the view, typically from a nib.</span><br><span class="line"></span><br><span class="line"> // 给系统NSObject类动态添加属性name</span><br><span class="line"></span><br><span class="line"> NSObject *objc = [[NSObject alloc] init];</span><br><span class="line"> objc.name = @"小码哥";</span><br><span class="line"> NSLog(@"%@",objc.name);</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">@end</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">// 定义关联的key</span><br><span class="line">static const char *key = "name";</span><br><span class="line"></span><br><span class="line">@implementation NSObject (Property)</span><br><span class="line"></span><br><span class="line">- (NSString *)name</span><br><span class="line">{</span><br><span class="line"> // 根据关联的key,获取关联的值。</span><br><span class="line"> return objc_getAssociatedObject(self, key);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">- (void)setName:(NSString *)name</span><br><span class="line">{</span><br><span class="line"> // 第一个参数:给哪个对象添加关联</span><br><span class="line"> // 第二个参数:关联的key,通过这个key获取</span><br><span class="line"> // 第三个参数:关联的value</span><br><span class="line"> // 第四个参数:关联的策略</span><br><span class="line"> objc_setAssociatedObject(self, key, name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">@end</span><br></pre></td></tr></table></figure>
<h4 id="字典转模型"><a href="#字典转模型" class="headerlink" title="字典转模型"></a>字典转模型</h4><ul>
<li>设计模型:字典转模型的第一步<ul>
<li>模型属性,通常需要跟字典中的key一一对应</li>
<li>问题:一个一个的生成模型属性,很慢?</li>
<li>需求:能不能自动根据一个字典,生成对应的属性。</li>
<li>解决:提供一个分类,专门根据字典生成对应的属性字符串。</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><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></pre></td><td class="code"><pre><span class="line"> @implementation NSObject (Log)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">// 自动打印属性字符串</span><br><span class="line">+ (void)resolveDict:(NSDictionary *)dict{</span><br><span class="line"></span><br><span class="line"> // 拼接属性字符串代码</span><br><span class="line"> NSMutableString *strM = [NSMutableString string];</span><br><span class="line"></span><br><span class="line"> // 1.遍历字典,把字典中的所有key取出来,生成对应的属性代码</span><br><span class="line"> [dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {</span><br><span class="line"></span><br><span class="line"> // 类型经常变,抽出来</span><br><span class="line"> NSString *type;</span><br><span class="line"></span><br><span class="line"> if ([obj isKindOfClass:NSClassFromString(@"__NSCFString")]) {</span><br><span class="line"> type = @"NSString";</span><br><span class="line"> }else if ([obj isKindOfClass:NSClassFromString(@"__NSCFArray")]){</span><br><span class="line"> type = @"NSArray";</span><br><span class="line"> }else if ([obj isKindOfClass:NSClassFromString(@"__NSCFNumber")]){</span><br><span class="line"> type = @"int";</span><br><span class="line"> }else if ([obj isKindOfClass:NSClassFromString(@"__NSCFDictionary")]){</span><br><span class="line"> type = @"NSDictionary";</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"> NSString *str;</span><br><span class="line"> if ([type containsString:@"NS"]) {</span><br><span class="line"> str = [NSString stringWithFormat:@"@property (nonatomic, strong) %@ *%@;",type,key];</span><br><span class="line"> }else{</span><br><span class="line"> str = [NSString stringWithFormat:@"@property (nonatomic, assign) %@ %@;",type,key];</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> // 每生成属性字符串,就自动换行。</span><br><span class="line"> [strM appendFormat:@"\n%@\n",str];</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"> NSLog(@"%@",strM);</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">@end</span><br></pre></td></tr></table></figure>
<ul>
<li>字典转模型的方式一:KVC</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">@implementation Status</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">+ (instancetype)statusWithDict:(NSDictionary *)dict</span><br><span class="line">{</span><br><span class="line"> Status *status = [[self alloc] init];</span><br><span class="line"></span><br><span class="line"> [status setValuesForKeysWithDictionary:dict];</span><br><span class="line"></span><br><span class="line"> return status;</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">@end</span><br></pre></td></tr></table></figure>
<ul>
<li>KVC字典转模型弊端:必须保证,模型中的属性和字典中的key一一对应。<ul>
<li>如果不一致,就会调用<code>[<Status 0x7fa74b545d60> setValue:forUndefinedKey:]</code> 报key找不到的错。</li>
<li>分析:模型中的属性和字典的key不一一对应,系统就会调用<code>setValue:forUndefinedKey:</code>报错。</li>
<li>解决:重写对象的<code>setValue:forUndefinedKey:</code>,把系统的方法覆盖, 就能继续使用KVC,字典转模型了。</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></pre></td><td class="code"><pre><span class="line">- (void)setValue:(id)value forUndefinedKey:(NSString *)key</span><br><span class="line">{</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<ul>
<li>字典转模型的方式二:Runtime<ul>
<li>思路:利用运行时,遍历模型中所有属性,根据模型的属性名,去字典中查找key,取出对应的值,给模型的属性赋值。</li>
<li>步骤:提供一个NSObject分类,专门字典转模型,以后所有模型都可以通过这个分类转。</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><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><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br></pre></td><td class="code"><pre><span class="line">@implementation ViewController</span><br><span class="line"></span><br><span class="line">- (void)viewDidLoad {</span><br><span class="line"> [super viewDidLoad];</span><br><span class="line"> // Do any additional setup after loading the view, typically from a nib.</span><br><span class="line"></span><br><span class="line"> // 解析Plist文件</span><br><span class="line"> NSString *filePath = [[NSBundle mainBundle] pathForResource:@"status.plist" ofType:nil];</span><br><span class="line"></span><br><span class="line"> NSDictionary *statusDict = [NSDictionary dictionaryWithContentsOfFile:filePath];</span><br><span class="line"></span><br><span class="line"> // 获取字典数组</span><br><span class="line"> NSArray *dictArr = statusDict[@"statuses"];</span><br><span class="line"></span><br><span class="line"> // 自动生成模型的属性字符串</span><br><span class="line">// [NSObject resolveDict:dictArr[0][@"user"]];</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> _statuses = [NSMutableArray array];</span><br><span class="line"></span><br><span class="line"> // 遍历字典数组</span><br><span class="line"> for (NSDictionary *dict in dictArr) {</span><br><span class="line"></span><br><span class="line"> Status *status = [Status modelWithDict:dict];</span><br><span class="line"></span><br><span class="line"> [_statuses addObject:status];</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"> NSLog(@"%@ %@",_statuses,[_statuses[0] user]);</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">@end</span><br><span class="line"></span><br><span class="line">@implementation NSObject (Model)</span><br><span class="line"></span><br><span class="line">+ (instancetype)modelWithDict:(NSDictionary *)dict</span><br><span class="line">{</span><br><span class="line"> // 思路:遍历模型中所有属性-》使用运行时</span><br><span class="line"></span><br><span class="line"> // 0.创建对应的对象</span><br><span class="line"> id objc = [[self alloc] init];</span><br><span class="line"></span><br><span class="line"> // 1.利用runtime给对象中的成员属性赋值</span><br><span class="line"></span><br><span class="line"> // class_copyIvarList:获取类中的所有成员属性</span><br><span class="line"> // Ivar:成员属性的意思</span><br><span class="line"> // 第一个参数:表示获取哪个类中的成员属性</span><br><span class="line"> // 第二个参数:表示这个类有多少成员属性,传入一个Int变量地址,会自动给这个变量赋值</span><br><span class="line"> // 返回值Ivar *:指的是一个ivar数组,会把所有成员属性放在一个数组中,通过返回的数组就能全部获取到。</span><br><span class="line"> /* 类似下面这种写法</span><br><span class="line"></span><br><span class="line"> Ivar ivar;</span><br><span class="line"> Ivar ivar1;</span><br><span class="line"> Ivar ivar2;</span><br><span class="line"> // 定义一个ivar的数组a</span><br><span class="line"> Ivar a[] = {ivar,ivar1,ivar2};</span><br><span class="line"></span><br><span class="line"> // 用一个Ivar *指针指向数组第一个元素</span><br><span class="line"> Ivar *ivarList = a;</span><br><span class="line"></span><br><span class="line"> // 根据指针访问数组第一个元素</span><br><span class="line"> ivarList[0];</span><br><span class="line"></span><br><span class="line"> */</span><br><span class="line"> unsigned int count;</span><br><span class="line"></span><br><span class="line"> // 获取类中的所有成员属性</span><br><span class="line"> Ivar *ivarList = class_copyIvarList(self, &count);</span><br><span class="line"></span><br><span class="line"> for (int i = 0; i < count; i++) {</span><br><span class="line"> // 根据角标,从数组取出对应的成员属性</span><br><span class="line"> Ivar ivar = ivarList[i];</span><br><span class="line"></span><br><span class="line"> // 获取成员属性名</span><br><span class="line"> NSString *name = [NSString stringWithUTF8String:ivar_getName(ivar)];</span><br><span class="line"></span><br><span class="line"> // 处理成员属性名->字典中的key</span><br><span class="line"> // 从第一个角标开始截取</span><br><span class="line"> NSString *key = [name substringFromIndex:1];</span><br><span class="line"></span><br><span class="line"> // 根据成员属性名去字典中查找对应的value</span><br><span class="line"> id value = dict[key];</span><br><span class="line"></span><br><span class="line"> // 二级转换:如果字典中还有字典,也需要把对应的字典转换成模型</span><br><span class="line"> // 判断下value是否是字典</span><br><span class="line"> if ([value isKindOfClass:[NSDictionary class]]) {</span><br><span class="line"> // 字典转模型</span><br><span class="line"> // 获取模型的类对象,调用modelWithDict</span><br><span class="line"> // 模型的类名已知,就是成员属性的类型</span><br><span class="line"></span><br><span class="line"> // 获取成员属性类型</span><br><span class="line"> NSString *type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];</span><br><span class="line"> // 生成的是这种@"@\"User\"" 类型 -》 @"User" 在OC字符串中 \" -> ",\是转义的意思,不占用字符</span><br><span class="line"> // 裁剪类型字符串</span><br><span class="line"> NSRange range = [type rangeOfString:@"\""];</span><br><span class="line"></span><br><span class="line"> type = [type substringFromIndex:range.location + range.length];</span><br><span class="line"></span><br><span class="line"> range = [type rangeOfString:@"\""];</span><br><span class="line"></span><br><span class="line"> // 裁剪到哪个角标,不包括当前角标</span><br><span class="line"> type = [type substringToIndex:range.location];</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> // 根据字符串类名生成类对象</span><br><span class="line"> Class modelClass = NSClassFromString(type);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> if (modelClass) { // 有对应的模型才需要转</span><br><span class="line"></span><br><span class="line"> // 把字典转模型</span><br><span class="line"> value = [modelClass modelWithDict:value];</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"> // 三级转换:NSArray中也是字典,把数组中的字典转换成模型.</span><br><span class="line"> // 判断值是否是数组</span><br><span class="line"> if ([value isKindOfClass:[NSArray class]]) {</span><br><span class="line"> // 判断对应类有没有实现字典数组转模型数组的协议</span><br><span class="line"> if ([self respondsToSelector:@selector(arrayContainModelClass)]) {</span><br><span class="line"></span><br><span class="line"> // 转换成id类型,就能调用任何对象的方法</span><br><span class="line"> id idSelf = self;</span><br><span class="line"></span><br><span class="line"> // 获取数组中字典对应的模型</span><br><span class="line"> NSString *type = [idSelf arrayContainModelClass][key];</span><br><span class="line"></span><br><span class="line"> // 生成模型</span><br><span class="line"> Class classModel = NSClassFromString(type);</span><br><span class="line"> NSMutableArray *arrM = [NSMutableArray array];</span><br><span class="line"> // 遍历字典数组,生成模型数组</span><br><span class="line"> for (NSDictionary *dict in value) {</span><br><span class="line"> // 字典转模型</span><br><span class="line"> id model = [classModel modelWithDict:dict];</span><br><span class="line"> [arrM addObject:model];</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> // 把模型数组赋值给value</span><br><span class="line"> value = arrM;</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"> if (value) { // 有值,才需要给模型的属性赋值</span><br><span class="line"> // 利用KVC给模型中的属性赋值</span><br><span class="line"> [objc setValue:value forKey:key];</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"> return objc;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">@end</span><br></pre></td></tr></table></figure>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</div>
</article>
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="http://yoursite.com/2019/03/21/2019新篇章/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Hack">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.gif">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Hack'Blog">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2019/03/21/2019新篇章/" itemprop="url">2019新篇章</a></h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Post created" itemprop="dateCreated datePublished" datetime="2019-03-21T09:28:45+08:00">
2019-03-21
</time>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<blockquote>
<p>新年新计划</p>
</blockquote>
<h5 id="1-深入学习Swift、Python、Nodejs、Java、PHP编程语言"><a href="#1-深入学习Swift、Python、Nodejs、Java、PHP编程语言" class="headerlink" title="1.深入学习Swift、Python、Nodejs、Java、PHP编程语言"></a>1.深入学习Swift、Python、Nodejs、Java、PHP编程语言</h5><h4 id="2-ReactNative-开发、小程序开发、逆向开发、Mac-os开发"><a href="#2-ReactNative-开发、小程序开发、逆向开发、Mac-os开发" class="headerlink" title="2.ReactNative 开发、小程序开发、逆向开发、Mac os开发"></a>2.ReactNative 开发、小程序开发、逆向开发、Mac os开发</h4><h4 id="3-上架自己的3-5款APP"><a href="#3-上架自己的3-5款APP" class="headerlink" title="3.上架自己的3-5款APP"></a>3.上架自己的3-5款APP</h4><h4 id="4-巩固基础知识、薪资达到20K月薪"><a href="#4-巩固基础知识、薪资达到20K月薪" class="headerlink" title="4.巩固基础知识、薪资达到20K月薪"></a>4.巩固基础知识、薪资达到20K月薪</h4>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</div>
</article>
<article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
<div class="post-block">
<link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/10/30/iOS大牛技术博客收藏/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="name" content="Hack">
<meta itemprop="description" content="">
<meta itemprop="image" content="/images/avatar.gif">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Hack'Blog">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
<a class="post-title-link" href="/2018/10/30/iOS大牛技术博客收藏/" itemprop="url">iOS大牛技术博客收藏</a></h1>
<div class="post-meta">
<span class="post-time">
<span class="post-meta-item-icon">
<i class="fa fa-calendar-o"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Post created" itemprop="dateCreated datePublished" datetime="2018-10-30T11:25:13+08:00">
2018-10-30
</time>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h3 id="iOS大牛技术博客收藏贴"><a href="#iOS大牛技术博客收藏贴" class="headerlink" title="iOS大牛技术博客收藏贴"></a>iOS大牛技术博客收藏贴</h3><ul>
<li><p><a href="http://www.tanhao.me/" target="_blank" rel="noopener">谭灏的博客:目前就职于腾讯mac管家部门,他是一名 OSX、iOS 程序员,他的博客中有许多mac,ios开发的文章,值得大家去品读</a></p>
</li>
<li><p><a href="https://www.jianshu.com/u/b82d2721ba07" target="_blank" rel="noopener">叶孤城的博客:就职于百度</a></p>
</li>
<li><p><a href="http://southpeak.github.io/" target="_blank" rel="noopener">南峰子的博客:就职于百度</a></p>
</li>
<li><p><a href="http://nianxi.net" target="_blank" rel="noopener">吴茜的博客:目前就职阿里旗下蚂蚁金服</a></p>
</li>
<li><p><a href="https://github.com/ChenYilong" target="_blank" rel="noopener">ChenYilong的Github:曾就职于leancloud,现就职于猿题库</a></p>
</li>
<li><p><a href="http://gracelancy.com/" target="_blank" rel="noopener">晨钰Lancy 猿题库 iOS 研发工程师</a></p>