-
Notifications
You must be signed in to change notification settings - Fork 0
/
16791200795383.html
1812 lines (1693 loc) · 145 KB
/
16791200795383.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 lang="zh">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=0.8,minimum-scale=0.8, maximum-scale=0.8,user-scalable=no,viewport-fit=cover">
<title>
面试 (九) :专虐面试官 - 宋明的博客
</title>
<link href="atom.xml" rel="alternate" title="宋明的博客" type="application/atom+xml">
<link rel="stylesheet" href="asset/css/style.min.css">
<link rel="stylesheet" href="asset/css/doc.css">
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/css/font-awesome.min.css">
<!-- Global site tag (gtag.js) - Google Analytics -->
<!-- 百度分析 -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/L2Dwidget.min.js"></script>
<script src="asset/app.js"></script>
</head>
<body style="overflow-x: hidden;">
<section class="hero">
<div class="hero-head">
<nav class="navbar" role="navigation" aria-label="main navigation">
<div class="container">
<div class="navbar-brand">
<a target="self" class="navbar-item " href="index.html">Home</a>
<a target="_self" class="navbar-item " href="archives.html">Archives</a>
<a role="button" id="navbarSNSRssSwitchBtn" class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navbarSNSRssButtons">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>
<div id="navbarSNSRssButtons" class="navbar-menu">
<div class="navbar-start">
</div>
<div class="navbar-end">
<div class="navbar-item">
<!--buttons start-->
<div class="buttons">
<a href="mailto: [email protected]" target="_blank" title="email">
<span class="icon is-large has-text-grey-darker">
<svg class="svg-inline--fa fa-email fa-w-14 fa-lg" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1208" width="200" height="200"><path fill="currentColor" d="M935.335233 153.62202h-846.666656a84.666666 84.666666 0 0 0-84.666666 84.666666v550.333327a84.666666 84.666666 0 0 0 84.666666 84.666665h846.666656a84.666666 84.666666 0 0 0 84.666666-84.666665v-550.333327a84.666666 84.666666 0 0 0-84.666666-84.666666z m-27.293711 213.952665L557.558216 549.672927a94.993177 94.993177 0 0 1-87.065555 0.197555l-354.612218-182.202664a42.333333 42.333333 0 0 1 38.698311-75.308177l354.606573 182.202664a10.196689 10.196689 0 0 0 9.341556-0.022577l350.477662-182.089776a42.333333 42.333333 0 1 1 39.034155 75.127555z" fill="#2c2c2c" p-id="1209"></path></svg>
</span>
</a>
<a href="atom.xml" target="_blank" title="RSS">
<span class="icon is-large has-text-black-bis">
<svg class="svg-inline--fa fa-rss fa-w-14 fa-lg" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="rss" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" data-fa-i2svg=""><path fill="currentColor" d="M128.081 415.959c0 35.369-28.672 64.041-64.041 64.041S0 451.328 0 415.959s28.672-64.041 64.041-64.041 64.04 28.673 64.04 64.041zm175.66 47.25c-8.354-154.6-132.185-278.587-286.95-286.95C7.656 175.765 0 183.105 0 192.253v48.069c0 8.415 6.49 15.472 14.887 16.018 111.832 7.284 201.473 96.702 208.772 208.772.547 8.397 7.604 14.887 16.018 14.887h48.069c9.149.001 16.489-7.655 15.995-16.79zm144.249.288C439.596 229.677 251.465 40.445 16.503 32.01 7.473 31.686 0 38.981 0 48.016v48.068c0 8.625 6.835 15.645 15.453 15.999 191.179 7.839 344.627 161.316 352.465 352.465.353 8.618 7.373 15.453 15.999 15.453h48.068c9.034-.001 16.329-7.474 16.005-16.504z"></path></svg><!-- <i class="fas fa-rss fa-lg"></i> -->
</span>
</a>
</div>
<!--buttons end-->
</div>
</div>
</div>
</div>
</nav>
</div>
<div class="hero-body ct-body"></div>
</section>
<section class="ct-body">
<div class="container">
<div class="columns is-variable bd-klmn-columns is-4">
<div class="column is-two-thirds">
<div class="post-body single-content">
<div class="card-image">
<figure class="random-img">
</figure>
</div>
<h1 class="title">
面试 (九) :专虐面试官
</h1>
<div class="media">
<figure class="media-left">
<p class="image is-48x48">
<img class="is-rounded" src="">
</p>
</figure>
<div class="media-content">
<div class="content">
<p style="line-height: 30px; font-size: 12px;">
<a href="http://apolla.cc">宋明</a>
<span style="color: #ccc;">|</span>
<span class="date"><i class="fa fa-calendar-check-o" aria-hidden="true"></i> 2023/03/18</span>
<span class="tran-posted-in">posted in</span>
<span class="posted-in"><a href='%E8%91%B5%E8%8A%B1%E5%AE%9D%E5%85%B8.html'><i class="fa fa-folder" aria-hidden="true"></i> 葵花宝典</a></span>
</p>
</div>
</div>
</div>
</div>
<article class="markdown-body single-content">
<p>2015年11月25日 星期三<br />
14:13</p>
<h3><a id="1%E4%BD%A0%E5%AE%9E%E7%8E%B0%E8%BF%87%E4%B8%80%E4%B8%AA%E6%A1%86%E6%9E%B6%E6%88%96%E8%80%85%E5%BA%93%E4%BB%A5%E4%BE%9B%E5%88%AB%E4%BA%BA%E4%BD%BF%E7%94%A8%E4%B9%88%EF%BC%9F%E5%A6%82%E6%9E%9C%E6%9C%89%EF%BC%8C%E8%AF%B7%E8%B0%88%E4%B8%80%E8%B0%88%E6%9E%84%E5%BB%BA%E6%A1%86%E6%9E%B6%E6%88%96%E8%80%85%E5%BA%93%E6%97%B6%E5%80%99%E7%9A%84%E7%BB%8F%E9%AA%8C%EF%BC%9B%E5%A6%82%E6%9E%9C%E6%B2%A1%E6%9C%89%EF%BC%8C%E8%AF%B7%E8%AE%BE%E6%83%B3%E5%92%8C%E8%AE%BE%E8%AE%A1%E6%A1%86%E6%9E%B6%E7%9A%84-public%E7%9A%84api%EF%BC%8C%E5%B9%B6%E6%8C%87%E5%87%BA%E5%A4%A7%E6%A6%82%E9%9C%80%E8%A6%81%E5%A6%82%E4%BD%95%E5%81%9A%E3%80%81%E9%9C%80%E8%A6%81%E6%B3%A8%E6%84%8F%E4%B8%80%E4%BA%9B%E4%BB%80%E4%B9%88%E6%96%B9%E9%9D%A2%EF%BC%8C%E6%9D%A5%E4%BD%BF%E5%88%AB%E4%BA%BA%E5%AE%B9%E6%98%93%E5%9C%B0%E4%BD%BF%E7%94%A8%E4%BD%A0%E7%9A%84%E6%A1%86%E6%9E%B6%E3%80%82" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>1.你实现过一个框架或者库以供别人使用么?如果有,请谈一谈构建框架或者库时候的经验;如果没有,请设想和设计框架的public的API,并指出大概需要如何做、需要注意一些什么方面,来使别人容易地使用你的框架。</h3>
<p>抽象和封装,方便使用。首先是对问题有充分的了解,比如构建一个文件解压压缩框架,从使用者的角度出发,只需关注发送给框架一个解压请求,框架完成复杂文件的解压操作,并且在适当的时候通知给是哦难过者,如解压完成、解压出错等。在框架内部去构建对象的关系,通过抽象让其更为健壮、便于更改。其次是API的说明文档.<br />
1.提供给外界的接口功能是否实用、够用<br />
2.别人使用我的框架时,能不能根据类名、方法名就猜出接口的具体作用<br />
3.别人调用接口时,提供的参数是否够用、调用起来是否简单<br />
4.别人使用我的框架时,要不要再导入依赖其他的框架</p>
<h3><a id="2%E4%BD%A0%E5%9C%A8%E5%AE%9E%E9%99%85%E5%BC%80%E5%8F%91%E4%B8%AD%EF%BC%8C%E6%9C%89%E5%93%AA%E4%BA%9B%E6%89%8B%E6%9C%BA%E6%9E%B6%E6%9E%84%E4%B8%8E%E6%80%A7%E8%83%BD%E8%B0%83%E8%AF%95%E7%BB%8F%E9%AA%8C" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>2.你在实际开发中,有哪些手机架构与性能调试经验</h3>
<p>1>刚接手公司的旧项目时,模块特别多,而且几乎所有的代码都写在控制器里面,比如UI控件代码、网络请求代码、数据存储代码<br />
2>接下来采取MVC模式进行封装、重构<br />
自定义UI控件封装内部的业务逻辑<br />
封装网络请求工具类<br />
封装数据存储工具类</p>
<p>使用NSOperation发送异步网络请求,使用NSOperationQueue管理线程数目及优先级,底层是用NSURLConnetion,详细可见开源框架<a href="https://github.com/xunyn/LWConnetionDemo">LWConnetion</a>。</p>
<h3><a id="kvo-delegation-nsnotification" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>KVO Delegation NSNotification</h3>
<p>通知<br />
通知比较灵活,不需要编写多少代码,实现比较简单;<br />
对于一个发出的通知,多个对象能够做出反应,即1对多的方式<br />
代理<br />
代理的语法比较严格,如果delegate中的一个方法没有实现那么就会出现编译警告<br />
需要定义很多代码</p>
<h3><a id="kvo" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>KVO</h3>
<p>KVO性能不好(底层会动态产生新的类),只能监听某个对象属性的改变<br />
2. KVO内部实现原理<br />
KVO是基于runtime机制实现的<br />
当某个类的对象第一次被观察时, 系统就会在运行期动态地创建该类的一个派生类,在这个派生类中重写基类中任何被观察属性的setter方法。<br />
派生类在被重写的setter方法实现真正的通知机制(Person NSKVONotifying_Person)</p>
<h3><a id="%E5%A4%9A%E5%9B%BE%E7%89%87%E4%B8%8B%E8%BD%BD" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>多图片下载</h3>
<h3><a id="object-c%E7%9A%84%E7%B1%BB%E5%8F%AF%E4%BB%A5%E5%A4%9A%E9%87%8D%E7%BB%A7%E6%89%BF%E4%B9%88%E5%8F%AF%E4%BB%A5%E5%AE%9E%E7%8E%B0%E5%A4%9A%E4%B8%AA%E6%8E%A5%E5%8F%A3%E4%B9%88-category%E6%98%AF%E4%BB%80%E4%B9%88%E9%87%8D%E5%86%99%E4%B8%80%E4%B8%AA%E7%B1%BB%E7%9A%84%E6%96%B9%E5%BC%8F%E7%94%A8%E7%BB%A7%E6%89%BF%E5%A5%BD%E8%BF%98%E6%98%AF%E5%88%86%E7%B1%BB%E5%A5%BD%E4%B8%BA%E4%BB%80%E4%B9%88" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么?</h3>
<p>答:Object-c的类不可以多重继承;可以实现多个接口,通过实现多个接口可以完成C++的多重继承;<br />
Category是类别,一般情况用分类好,用Category去重写类的方法,仅对本Category有效,不会影响到其他类与原有类的关</p>
<h3><a id="import%E8%B7%9F-include%E5%8F%88%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%EF%BC%8C-class%E5%91%A2-import%E8%B7%9F-import%E2%80%9D%E5%8F%88%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>#import跟#include又什么区别,@class呢, #import<>跟#import”又什么区别?</h3>
<p>答:#import是Objective-C导入头文件的关键字,#include是C/C++导入头文件的关键字,使用#import头文件会自动只导入一次,不会重复导入,相当于#include和#pragma once;@class告诉编译器某个类的声明,当执行时,才去查看类的实现文件,可以解决头文件的相互包含;#import<>用来包含系统的头文件,#import””用来包含用户头文件。</p>
<h3><a id="%E5%B1%9E%E6%80%A7readwrite%EF%BC%8Creadonly%EF%BC%8Cassign%EF%BC%8Cretain%EF%BC%8Ccopy%EF%BC%8Cnonatomic%E5%90%84%E6%98%AF%E4%BB%80%E4%B9%88%E4%BD%9C%E7%94%A8%EF%BC%8C%E5%9C%A8%E9%82%A3%E7%A7%8D%E6%83%85%E5%86%B5%E4%B8%8B%E7%94%A8" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>属性readwrite,readonly,assign,retain,copy,nonatomic各是什么作用,在那种情况下用?</h3>
<p>readwrite是可读可写特性;需要生成getter方法和setter方法时<br />
readonly是只读特性 只会生成getter方法 不会生成setter方法;不希望属性在类外改变<br />
assign是赋值特性,setter方法将传入参数赋值给实例变量;仅设置变量时;<br />
retain表示持有特性,setter方法将传入参数先保留,再赋值,传入参数的retaincount会+1;<br />
copy表示赋值特性,setter方法将传入对象复制一份;需要完全一份新的变量时。<br />
nonatomic非原子操作,决定编译器生成的setter getter是否是原子操作,atomic表示多线程安全,一般使用nonatomic</p>
<h3><a id="%E5%86%99%E4%B8%80%E4%B8%AAsetter%E6%96%B9%E6%B3%95%E7%94%A8%E4%BA%8E%E5%AE%8C%E6%88%90-property-nonatomic-retain-nsstring-name%E5%86%99%E4%B8%80%E4%B8%AA-setter%E6%96%B9%E6%B3%95%E7%94%A8%E4%BA%8E%E5%AE%8C%E6%88%90-property-nonatomic%EF%BC%8Ccopy-nsstring-name" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>写一个setter方法用于完成@property(nonatomic,retain)NSString *name,写一个setter方法用于完成@property(nonatomic,copy)NSString *name</h3>
<ul>
<li>
<p>(void) setName:(NSString*) str<br />
{<br />
[str retain];<br />
[name release];<br />
name = str;<br />
}</p>
</li>
<li>
<p>(void)setName:(NSString *)str<br />
{</p>
</li>
</ul>
<p>id t = [str copy];<br />
[name release];<br />
name = t;</p>
<p>}</p>
<h3><a id="%E5%AF%B9%E4%BA%8E%E8%AF%AD%E5%8F%A5nsstring-obj-nsdata-alloc-init-obj%E5%9C%A8%E7%BC%96%E8%AF%91%E6%97%B6%E5%92%8C%E8%BF%90%E8%A1%8C%E6%97%B6%E5%88%86%E5%88%AB%E6%97%B6%E4%BB%80%E4%B9%88%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%AF%B9%E8%B1%A1" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>对于语句NSString*obj = [[NSData alloc] init]; obj在编译时和运行时分别时什么类型的对象?</h3>
<p>编译时是NSString的类型;运行时是NSData类型的对象</p>
<h3><a id="%E5%B8%B8%E8%A7%81%E7%9A%84object-c%E7%9A%84%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E6%9C%89%E9%82%A3%E4%BA%9B%EF%BC%8C%E5%92%8C-c%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%E5%A6%82%EF%BC%9A-nsinteger%E5%92%8Cint" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>常见的object-c的数据类型有那些, 和C的基本数据类型有什么区别?如:NSInteger和int</h3>
<p>答:object-c的数据类型有NSString,NSNumber,NSArray,NSMutableArray,NSData等等,这些都是class,创建后便是对象,而C语言的基本数据类型int,只是一定字节的内存空间,用于存放数值;NSInteger是基本数据类型,并不是NSNumber的子类,当然也不是NSObject的子类。NSInteger是基本数据类型Int或者Long的别名(NSInteger的定义typedef longNSInteger),它的区别在于,NSInteger会根据系统是32位还是64位来决定是本身是int还是Long。</p>
<h3><a id="id%E5%A3%B0%E6%98%8E%E7%9A%84%E5%AF%B9%E8%B1%A1%E6%9C%89%E4%BB%80%E4%B9%88%E7%89%B9%E6%80%A7" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>id声明的对象有什么特性?</h3>
<p>答:Id声明的对象具有运行时的特性,即可以指向任意类型的objcetive-c的对象;</p>
<h3><a id="objective-c%E5%A6%82%E4%BD%95%E5%AF%B9%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86%E7%9A%84" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>Objective-C如何对内存管理的?</h3>
<p>答:Objective-C的内存管理主要有三种方式ARC(自动引用计数)、MRC(手动内存计数)、autorelease(自动释放池)。</p>
<h3><a id="%E5%8E%9F%E5%AD%90atomic%E8%B7%9F%E9%9D%9E%E5%8E%9F%E5%AD%90-non-atomic%E5%B1%9E%E6%80%A7%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>原子(atomic)跟非原子(non-atomic)属性有什么区别?</h3>
<p>atomic提供多线程安全。是防止在写未完成的时候被另外一个线程读取,造成数据错误<br />
non-atomic:在自己管理内存的环境中,解析的访问器保留并自动释放返回的值,如果指定了nonatomic,那么访问器只是简单地返回这个值。</p>
<h3><a id="%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86%E7%9A%84%E5%87%A0%E6%9D%A1%E5%8E%9F%E5%88%99%E6%97%B6%E4%BB%80%E4%B9%88%E6%8C%89%E7%85%A7%E9%BB%98%E8%AE%A4%E6%B3%95%E5%88%99%E9%82%A3%E4%BA%9B%E5%85%B3%E9%94%AE%E5%AD%97%E7%94%9F%E6%88%90%E7%9A%84%E5%AF%B9%E8%B1%A1%E9%9C%80%E8%A6%81%E6%89%8B%E5%8A%A8%E9%87%8A%E6%94%BE%E5%9C%A8%E5%92%8Cproperty%E7%BB%93%E5%90%88%E7%9A%84%E6%97%B6%E5%80%99%E6%80%8E%E6%A0%B7%E6%9C%89%E6%95%88%E7%9A%84%E9%81%BF%E5%85%8D%E5%86%85%E5%AD%98%E6%B3%84%E9%9C%B2" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>内存管理的几条原则时什么?按照默认法则.那些关键字生成的对象需要手动释放?在和property结合的时候怎样有效的避免内存泄露?</h3>
<p>谁申请,谁释放<br />
遵循Cocoa Touch的使用原则;<br />
内存管理主要要避免“过早释放”和“内存泄漏”,对于“过早释放”需要注意@property设置特性时,一定要用对特性关键字,对于“内存泄漏”,一定要申请了要负责释放,要细心。<br />
关键字alloc或new生成的对象需要手动释放;<br />
设置正确的property属性,对于retain需要在合适的地方释放,</p>
<h3><a id="%E5%A6%82%E4%BD%95%E5%AF%B9ios%E8%AE%BE%E5%A4%87%E8%BF%9B%E8%A1%8C%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>如何对iOS设备进行性能测试?</h3>
<p>Profile-> Instruments ->Time Profiler</p>
<h3><a id="object-c%E4%B8%AD%E5%88%9B%E5%BB%BA%E7%BA%BF%E7%A8%8B%E7%9A%84%E6%96%B9%E6%B3%95%E6%98%AF%E4%BB%80%E4%B9%88%E5%A6%82%E6%9E%9C%E5%9C%A8%E4%B8%BB%E7%BA%BF%E7%A8%8B%E4%B8%AD%E6%89%A7%E8%A1%8C%E4%BB%A3%E7%A0%81%EF%BC%8C%E6%96%B9%E6%B3%95%E6%98%AF%E4%BB%80%E4%B9%88%E5%A6%82%E6%9E%9C%E6%83%B3%E5%BB%B6%E6%97%B6%E6%89%A7%E8%A1%8C%E4%BB%A3%E7%A0%81%E3%80%81%E6%96%B9%E6%B3%95%E5%8F%88%E6%98%AF%E4%BB%80%E4%B9%88" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>Object C中创建线程的方法是什么?如果在主线程中执行代码,方法是什么?如果想延时执行代码、方法又是什么?</h3>
<p>答:线程创建有三种方法:使用NSThread创建、使用GCD的dispatch、使用子类化的NSOperation,然后将其加入NSOperationQueue;在主线程执行代码,方法是performSelectorOnMainThread,如果想延时执行代码可以用performSelector:onThread:withObject:waitUntilDone:</p>
<h3><a id="mvc%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F%E4%BD%A0%E8%BF%98%E7%86%9F%E6%82%89%E4%BB%80%E4%B9%88%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%EF%BC%9F" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>MVC设计模式是什么? 你还熟悉什么设计模式?</h3>
<p>设计模式:并不是一种新技术,而是一种编码经验,使用比如java中的接口,iphone中的协议,继承关系等基本手段,用比较成熟的逻辑去处理某一种类型的事情,总结为所谓设计模式。面向对象编程中,java已经归纳了23种设计模式。</p>
<p>mvc设计模式 :模型,视图,控制器,可以将整个应用程序在思想上分成三大块,对应是的数据的存储或处理,前台的显示,业务逻辑的控制。Iphone本身的设计思想就是遵循mvc设计模式。其不属于23种设计模式范畴。</p>
<p>代理模式:代理模式给某一个对象提供一个代理对象,并由代理对象控制对源对象的引用.比如一个工厂生产了产品,并不想直接卖给用户,而是搞了很多代理商,用户可以直接找代理商买东西,代理商从工厂进货.常见的如QQ的自动回复就属于代理拦截,代理模式在iphone中得到广泛应用.</p>
<p>单例模式:说白了就是一个类不通过alloc方式创建对象,而是用一个静态方法返回这个类的对象。系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为,比如想获得[UIApplication sharedApplication];任何地方调用都可以得到UIApplication的对象,这个对象是全局唯一的。</p>
<p>观察者模式: 当一个物体发生变化时,会通知所有观察这个物体的观察者让其做出反应。实现起来无非就是把所有观察者的对象给这个物体,当这个物体的发生改变,就会调用遍历所有观察者的对象调用观察者的方法从而达到通知观察者的目的。</p>
<p>工厂模式:</p>
<p>public class Factory {</p>
<p>public static Sample creator(int which ){</p>
<p>if (which==1)</p>
<p>return new SampleA();</p>
<p>else if (which==2)</p>
<p>return new SampleB();</p>
<p>}</p>
<p>}</p>
<h3><a id="%E7%B1%BB%E5%88%AB%E7%9A%84%E4%BD%9C%E7%94%A8%E7%BB%A7%E6%89%BF%E5%92%8C%E7%B1%BB%E5%88%AB%E5%9C%A8%E5%AE%9E%E7%8E%B0%E4%B8%AD%E6%9C%89%E4%BD%95%E5%8C%BA%E5%88%AB" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>类别的作用?继承和类别在实现中有何区别?</h3>
<p>答:category可以在不获悉,不改变原来代码的情况下往里面添加新的方法,只能添加,不能删除修改,并且如果类别和原来类中的方法产生名称冲突,则类别将覆盖原来的方法,因为类别具有更高的优先级。</p>
<p>类别主要有3个作用:</p>
<p>1).将类的实现分散到多个不同文件或多个不同框架中。</p>
<p>2).创建对私有方法的前向引用。</p>
<p>3).向对象添加非正式协议。</p>
<p>继承可以增加,修改或者删除方法,并且可以增加属性。</p>
<h3><a id="%E7%B1%BB%E5%88%AB%E5%92%8C%E7%B1%BB%E6%89%A9%E5%B1%95%E7%9A%84%E5%8C%BA%E5%88%AB%E3%80%82" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>类别和类扩展的区别。</h3>
<p>答:category和extensions的不同在于 后者可以添加属性。另外后者添加的方法是必须要实现的。<br />
extensions可以认为是一个私有的Category。</p>
<h3><a id="oc%E4%B8%AD%E7%9A%84%E5%8D%8F%E8%AE%AE%E5%92%8Cjava%E4%B8%AD%E7%9A%84%E6%8E%A5%E5%8F%A3%E6%A6%82%E5%BF%B5%E6%9C%89%E4%BD%95%E4%B8%8D%E5%90%8C" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>oc中的协议和java中的接口概念有何不同?</h3>
<p>答:OC中的代理有2层含义,官方定义为formal和informal protocol。前者和Java接口一样。<br />
informal protocol中的方法属于设计模式考虑范畴,不是必须实现的,但是如果有实现,就会改变类的属性。<br />
其实关于正式协议,类别和非正式协议我很早前学习的时候大致看过,也写在了学习教程里<br />
“非正式协议概念其实就是类别的另一种表达方式“这里有一些你可能希望实现的方法,你可以使用他们更好的完成工作”。<br />
现在来看,其实protocal已经开始对两者都统一和规范起来操作,因为资料中说“非正式协议使用interface修饰“,<br />
现在我们看到协议中两个修饰词:“必须实现(@requied)”和“可选实现(@optional)”。</p>
<h3><a id="%E4%BB%80%E4%B9%88%E6%98%AFkvo%E5%92%8Ckvc" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>什么是KVO和KVC?</h3>
<p>答:KVC:键–值编码是一种间接访问对象的属性使用字符串来标识属性,而不是通过调用存取方法,直接或通过实例变量访问的机制。</p>
<p>很多情况下可以简化程序代码。apple文档其实给了一个很好的例子。</p>
<p>KVO:键值观察机制,他提供了观察某一属性变化的方法,极大的简化了代码。</p>
<p>具体用看到嗯哼用到过的一个地方是对于按钮点击变化状态的的监控。</p>
<p>比如我自定义的一个button</p>
<p>[self addObserver:self forKeyPath:@"highlighted" options:0 context:nil];</p>
<p>#pragma mark KVO</p>
<ul>
<li>(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context</li>
</ul>
<p>{</p>
<p>if ([keyPath isEqualToString:@"highlighted"] ) {</p>
<p>[ self setNeedsDisplay];</p>
<p>}<br />
}<br />
对于系统是根据keypath去取的到相应的值发生改变,理论上来说是和kvc机制的道理是一样的。</p>
<p>对于kvc机制如何通过key寻找到value:</p>
<p>“当通过KVC调用对象时,比如:[selfvalueForKey:@”someKey”]时,程序会自动试图通过几种不同的方式解析这个调用。首先查找对象是否带有someKey这个方法,如果没找到,会继续查找对象是否带有someKey这个实例变量(iVar),如果还没有找到,程序会继续试图调用-(id) valueForUndefinedKey:这个方法。如果这个方法还是没有被实现的话,程序会抛出一个NSUndefinedKeyException异常错误。<br />
(cocoachina.com注:Key-Value Coding查找方法的时候,不仅仅会查找someKey这个方法,还会查找getsomeKey这个方法,前面加一个get,或者someKey以及getsomeKey这几种形式。同时,查找实例变量的时候也会不仅仅查找someKey这个变量,也会查找_someKey这个变量是否存在。) -设计valueForUndefinedKey:方法的主要目的是当你使用-(id)valueForKey方法从对象中请求值时,对象能够在错误发生前,有最后的机会响应这个请求。这样做有很多好处,下面的两个例子说明了这样做的好处。“</p>
<p>来至cocoa,这个说法应该挺有道理。</p>
<p>因为我们知道button却是存在一个highlighted实例变量.因此为何上面我们只是add一个相关的keypath就行了,</p>
<p>可以按照kvc查找的逻辑理解,就说的过去了。</p>
<h3><a id="%E4%BB%A3%E7%90%86%E7%9A%84%E4%BD%9C%E7%94%A8" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>代理的作用?</h3>
<p>答:代理的目的是改变或传递控制链。允许一个类在某些特定时刻通知到其他类,而不需要获取到那些类的指针。可以减少框架复杂度。</p>
<p>另外一点,代理可以理解为java中的回调监听机制的一种类似。</p>
<h3><a id="oc%E4%B8%AD%E5%8F%AF%E4%BF%AE%E6%94%B9%E5%92%8C%E4%B8%8D%E5%8F%AF%E4%BB%A5%E4%BF%AE%E6%94%B9%E7%B1%BB%E5%9E%8B%E3%80%82" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>oc中可修改和不可以修改类型。</h3>
<p>答:可修改不可修改的集合类。这个我个人简单理解就是可动态添加修改和不可动态添加修改一样。</p>
<p>比如NSArray和NSMutableArray。前者在初始化后的内存控件就是固定不可变的,后者可以添加等,可以动态申请新的内存空间。</p>
<h3><a id="%E6%88%91%E4%BB%AC%E8%AF%B4%E7%9A%84oc%E6%98%AF%E5%8A%A8%E6%80%81%E8%BF%90%E8%A1%8C%E6%97%B6%E8%AF%AD%E8%A8%80%E6%98%AF%E4%BB%80%E4%B9%88%E6%84%8F%E6%80%9D" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>我们说的oc是动态运行时语言是什么意思?</h3>
<p>答:多态。 主要是将数据类型的确定由编译时,推迟到了运行时。<br />
这个问题其实浅涉及到两个概念,运行时和多态。</p>
<p>简单来说,运行时机制使我们直到运行时才去决定一个对象的类别,以及调用该类别对象指定方法。</p>
<p>多态:不同对象以自己的方式响应相同的消息的能力叫做多态。意思就是假设生物类(life)都用有一个相同的方法-eat;</p>
<p>那人类属于生物,猪也属于生物,都继承了life后,实现各自的eat,但是调用是我们只需调用各自的eat方法。</p>
<p>也就是不同的对象以自己的方式响应了相同的消息(响应了eat这个选择器)。</p>
<p>因此也可以说,运行时机制是多态的基础?~~~</p>
<h3><a id="%E9%80%9A%E7%9F%A5%E5%92%8C%E5%8D%8F%E8%AE%AE%E7%9A%84%E4%B8%8D%E5%90%8C%E4%B9%8B%E5%A4%84" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>通知和协议的不同之处?</h3>
<p>答:协议有控制链(has-a)的关系,通知没有。</p>
<p>首先我一开始也不太明白,什么叫控制链(专业术语了~)。但是简单分析下通知和代理的行为模式,我们大致可以有自己的理解</p>
<p>简单来说,通知的话,它可以一对多,一条消息可以发送给多个消息接受者。</p>
<p>代理按我们的理解,到不是直接说不能一对多,比如我们知道的明星经济代理人,很多时候一个经济人负责好几个明星的事务。</p>
<p>只是对于不同明星间,代理的事物对象都是不一样的,一一对应,不可能说明天要处理A明星要一个发布会,代理人发出处理发布会的消息后,别称B的</p>
<p>发布会了。但是通知就不一样,他只关心发出通知,而不关心多少接收到感兴趣要处理。</p>
<p>因此控制链(has-a从英语单词大致可以看出,单一拥有和可控制的对应关系。</p>
<h3><a id="%E4%BB%80%E4%B9%88%E6%98%AF%E6%8E%A8%E9%80%81%E6%B6%88%E6%81%AF" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>什么是推送消息?</h3>
<p>答:推送通知更是一种技术。</p>
<p>简单点就是客户端获取资源的一种手段。</p>
<p>普通情况下,都是客户端主动的pull。</p>
<p>推送则是服务器端主动push。 测试push的实现可以查看该博文。</p>
<h3><a id="%E5%85%B3%E4%BA%8E%E5%A4%9A%E6%80%81%E6%80%A7" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>关于多态性</h3>
<p>答:多态,子类指针可以赋值给父类。</p>
<p>这个题目其实可以出到一切面向对象语言中,</p>
<p>因此关于多态,继承和封装基本最好都有个自我意识的理解,也并非一定要把书上资料上写的能背出来</p>
<h3><a id="%E5%AF%B9%E4%BA%8E%E5%8D%95%E4%BE%8B%E7%9A%84%E7%90%86%E8%A7%A3" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>对于单例的理解</h3>
<p>答:在objective-c中要实现一个单例类,至少需要做以下四个步骤:</p>
<p>1). 为单例对象实现一个静态实例,并初始化,然后设置成nil,</p>
<p>2).实现一个实例构造方法检查上面声明的静态实例是否为nil,如果是则新建并返回一个本类的实例,</p>
<p>3).重写allocWithZone方法,用来保证其他人直接使用alloc和init试图获得一个新实力的时候不产生一个新实例,</p>
<p>4).适当实现allocWitheZone,copyWithZone,release和autorelease。</p>
<h3><a id="%E8%AF%B4%E8%AF%B4%E5%93%8D%E5%BA%94%E9%93%BE" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>说说响应链</h3>
<p>答: 事件响应链。包括点击事件,画面刷新事件等。在视图栈内从上至下,或者从下之上传播。可以说点事件的分发,传递以及处理。具体可以去看下touch事件这块。因为问的太抽象化了严重怀疑题目出到越后面就越笼统。可以从责任链模式,来讲通过事件响应链处理,其拥有的扩展性</p>
<h3><a id="frame%E5%92%8Cbounds%E6%9C%89%E4%BB%80%E4%B9%88%E4%B8%8D%E5%90%8C" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>frame和bounds有什么不同?</h3>
<p>答:frame指的是:该view在父view坐标系统中的位置和大小。(参照点是父亲的坐标系统)</p>
<p>bounds指的是:该view在本身坐标系统中 的位置和大小。(参照点是本身坐标系统)</p>
<h3><a id="%E6%96%B9%E6%B3%95%E5%92%8C%E9%80%89%E6%8B%A9%E5%99%A8%E6%9C%89%E4%BD%95%E4%B8%8D%E5%90%8C" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>方法和选择器有何不同?</h3>
<p>答:selector是一个方法的名字,method是一个组合体,包含了名字和实现.<br />
详情可以看apple文档。</p>
<ol start="30">
<li>OC的垃圾回收机制?<br />
答:OC2.0有Garbage collection,但是iOS平台不提供。一般我们了解的objective-c对于内存管理都是手动操作的,但是也有自动释放池。但是差了大部分资料,貌似不要和arc机制搞混就好了。</li>
</ol>
<h3><a id="nsoperation-queue" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>NSOperation queue?</h3>
<p>答:存放NSOperation的集合类。</p>
<p>操作和操作队列,基本可以看成java中的线程和线程池的概念。用于处理ios多线程开发的问题。<br />
网上部分资料提到一点是,虽然是queue,但是却并不是带有队列的概念,放入的操作并非是按照严格的先进现出。<br />
这边又有个疑点是,对于队列来说,先进先出的概念是Afunc添加进队列,Bfunc紧跟着也进入队列,Afunc先执行这个是必然的,但是Bfunc是等Afunc完全操作完以后,B才开始启动并且执行,因此队列的概念离乱上有点违背了多线程处理这个概念。但是转念一想其实可以参考银行的取票和叫号系统。因此对于A比B先排队取票但是B率先执行完操作,我们亦然可以感性认为这还是一个队列。但是后来看到一票关于这操作队列话题的文章,其中有一句提到<br />
“因为两个操作提交的时间间隔很近,线程池中的线程,谁先启动是不定的。”<br />
瞬间觉得这个queue名字有点忽悠人了,还不如pool~<br />
综合一点,我们知道他可以比较大的用处在于可以帮组多线程编程就好了。</p>
<h3><a id="%E4%BB%80%E4%B9%88%E6%98%AF%E5%BB%B6%E8%BF%9F%E5%8A%A0%E8%BD%BD" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>什么是延迟加载?</h3>
<p>答:懒汉模式,只在用到的时候才去初始化。<br />
也可以理解成延时加载。<br />
我觉得最好也最简单的一个列子就是tableView中图片的加载显示了。</p>
<p>一个延时载,避免内存过高,一个异步加载,避免线程堵塞。</p>
<p>是否在一个视图控制器中嵌入两个tableview控制器?<br />
答:一个视图控制只提供了一个View视图,理论上一个tableViewController也不能放吧,只能说可以嵌入一个tableview视图。当然,题目本身也有歧义,如果不是我们定性思维认为的UIViewController,而是宏观的表示视图控制者,那我们倒是可以把其看成一个视图控制者,它可以控制多个视图控制器,比如TabbarController那样的感觉。</p>
<p>一个tableView是否可以关联两个不同的数据源?你会怎么处理?<br />
答:首先我们从代码来看,数据源如何关联上的,其实是在数据源关联的代理方法里实现的。</p>
<p>因此我们并不关心如何去关联他,他怎么关联上,方法只是让我返回根据自己的需要去设置如相关的数据源。</p>
<p>因此,我觉得可以设置多个数据源啊,但是有个问题是,你这是想干嘛呢?想让列表如何显示,不同的数据源分区块显示?</p>
<h3><a id="%E4%BB%80%E4%B9%88%E6%97%B6%E5%80%99%E4%BD%BF%E7%94%A8nsmutablearray%EF%BC%8C%E4%BB%80%E4%B9%88%E6%97%B6%E5%80%99%E4%BD%BF%E7%94%A8nsarray" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>什么时候使用NSMutableArray,什么时候使用NSArray?</h3>
<p>答:当数组在程序运行时,需要不断变化的,使用NSMutableArray,当数组在初始化后,便不再改变的,使用NSArray。需要指出的是,使用NSArray只表明的是该数组在运行时不发生改变,即不能往NSAarry的数组里新增和删除元素,但不表明其数组內的元素的内容不能发生改变。NSArray是线程安全的,NSMutableArray不是线程安全的,多线程使用到NSMutableArray需要注意。</p>
<h3><a id="%E7%BB%99%E5%87%BA%E5%A7%94%E6%89%98%E6%96%B9%E6%B3%95%E7%9A%84%E5%AE%9E%E4%BE%8B%EF%BC%8C%E5%B9%B6%E4%B8%94%E8%AF%B4%E5%87%BAuitableview%E7%9A%84data-source%E6%96%B9%E6%B3%95" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>给出委托方法的实例,并且说出UITableVIew的Data Source方法</h3>
<p>答:CocoaTouch框架中用到了大量委托,其中UITableViewDelegate就是委托机制的典型应用,是一个典型的使用委托来实现适配器模式,其中UITableViewDelegate协议是目标,tableview是适配器,实现UITableViewDelegate协议,并将自身设置为talbeview的delegate的对象,是被适配器,一般情况下该对象是UITableViewController。</p>
<p>UITableVIew的Data Source方法有- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;</p>
<p>(UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;</p>
<p>在应用中可以创建多少autorelease对象,是否有限制?</p>
<p>答案:无</p>
<h3><a id="%E5%A6%82%E6%9E%9C%E6%88%91%E4%BB%AC%E4%B8%8D%E5%88%9B%E5%BB%BA%E5%86%85%E5%AD%98%E6%B1%A0%EF%BC%8C%E6%98%AF%E5%90%A6%E6%9C%89%E5%86%85%E5%AD%98%E6%B1%A0%E6%8F%90%E4%BE%9B%E7%BB%99%E6%88%91%E4%BB%AC" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>如果我们不创建内存池,是否有内存池提供给我们?</h3>
<p>答:界面线程维护着自己的内存池,用户自己创建的数据线程,则需要创建该线程的内存池<br />
什么时候需要在程序中创建内存池?<br />
答:用户自己创建的数据线程,则需要创建该线程的内存池</p>
<h3><a id="%E7%B1%BBnsobject%E7%9A%84%E9%82%A3%E4%BA%9B%E6%96%B9%E6%B3%95%E7%BB%8F%E5%B8%B8%E8%A2%AB%E4%BD%BF%E7%94%A8" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>类NSObject的那些方法经常被使用?</h3>
<p>答:NSObject是Objetive-C的基类,其由NSObject类及一系列协议构成。</p>
<p>其中类方法alloc、class、description对象方法init、dealloc、– performSelector:withObject:afterDelay:等经常被使用</p>
<h3><a id="%E4%BB%80%E4%B9%88%E6%98%AF%E7%AE%80%E4%BE%BF%E6%9E%84%E9%80%A0%E6%96%B9%E6%B3%95" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>什么是简便构造方法?</h3>
<p>答:简便构造方法一般由CocoaTouch框架提供,如NSNumber的+ numberWithBool: + numberWithChar: + numberWithDouble: + numberWithFloat: + numberWithInt:</p>
<p>Foundation下大部分类均有简便构造方法,我们可以通过简便构造方法,获得系统给我们创建好的对象,并且不需要手动释放。</p>
<h3><a id="%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8xcode%E8%AE%BE%E8%AE%A1%E9%80%9A%E7%94%A8%E5%BA%94%E7%94%A8" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>如何使用Xcode设计通用应用?</h3>
<p>答:使用MVC模式设计应用,其中Model层完成脱离界面,即在Model层,其是可运行在任何设备上,在controller层,根据iPhone与iPad(独有UISplitViewController)的不同特点选择不同的viewController对象。在View层,可根据现实要求,来设计,其中以xib文件设计时,其设置其为universal。</p>
<h3><a id="uiview%E7%9A%84%E5%8A%A8%E7%94%BB%E6%95%88%E6%9E%9C%E6%9C%89%E9%82%A3%E4%BA%9B" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>UIView的动画效果有那些?</h3>
<p>答:有很多,如UIViewAnimationOptionCurveEaseInOut UIViewAnimationOptionCurveEaseIn UIViewAnimationOptionCurveEaseOut UIViewAnimationOptionTransitionFlipFromLeft UIViewAnimationOptionTransitionFlipFromRight UIViewAnimationOptionTransitionCurlUpUIViewAnimationOptionTransitionCurlDown</p>
<h3><a id="%E5%9C%A8iphone%E5%BA%94%E7%94%A8%E4%B8%AD%E5%A6%82%E4%BD%95%E4%BF%9D%E5%AD%98%E6%95%B0%E6%8D%AE" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>在iPhone应用中如何保存数据?</h3>
<p>答:有以下几种保存机制:</p>
<p>1).通过web服务,保存在服务器上</p>
<p>2).通过NSCoder固化机制,将对象保存在文件中</p>
<p>3).通过SQlite或CoreData保存在文件数据库中</p>
<h3><a id="%E4%BB%80%E4%B9%88%E6%98%AFcoredata" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>什么是coredata?</h3>
<p>答:coredata是苹果提供一套数据保存框架,其基于SQlite</p>
<h3><a id="%E4%BB%80%E4%B9%88%E6%98%AFnsmanagedobject%E6%A8%A1%E5%9E%8B" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>什么是NSManagedObject模型?</h3>
<p>答:NSManagedObject是NSObject的子类 ,也是coredata的重要组成部分,它是一个通用的类,实现了core data模型层所需的基本功能,用户可通过子类化NSManagedObject,建立自己的数据模型。</p>
<h3><a id="%E4%BB%80%E4%B9%88%E6%98%AFnsmanagedobjectcontext" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>什么是NSManagedobjectContext?</h3>
<p>答:NSManagedobjectContext对象负责应用和数据库之间的交互。</p>
<h3><a id="%E4%BB%80%E4%B9%88%E6%98%AF%E8%B0%93%E8%AF%8D" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>什么是谓词?</h3>
<p>答:谓词是通过NSPredicate,是通过给定的逻辑条件作为约束条件,完成对数据的筛选。</p>
<p>predicate = [NSPredicate predicateWithFormat:@"customerID == %d",n];</p>
<p>a = [customers filteredArrayUsingPredicate:predicate];</p>
<h3><a id="%E5%92%8Ccoredata%E4%B8%80%E8%B5%B7%E6%9C%89%E5%93%AA%E5%87%A0%E7%A7%8D%E6%8C%81%E4%B9%85%E5%8C%96%E5%AD%98%E5%82%A8%E6%9C%BA%E5%88%B6" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>和coredata一起有哪几种持久化存储机制?</h3>
<p>答:存入到文件、 存入到NSUserDefaults(系统plist文件中)、存入到Sqlite文件数据库</p>
<h3><a id="%E8%B0%88%E8%B0%88%E5%AF%B9block%E7%9A%84%E7%90%86%E8%A7%A3%E5%B9%B6%E5%86%99%E5%87%BA%E4%B8%80%E4%B8%AA%E4%BD%BF%E7%94%A8-block%E6%89%A7%E8%A1%8Cuivew%E5%8A%A8%E7%94%BB" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>谈谈对Block的理解?并写出一个使用Block执行UIVew动画?</h3>
<p>答:Block是可以获取其他函数局部变量的匿名函数,其不但方便开发,并且可以大幅提高应用的执行效率(多核心CPU可直接处理Block指令)</p>
<p>[UIView transitionWithView:self.view</p>
<p>duration:0.2</p>
<p>options:UIViewAnimationOptionTransitionFlipFromLeft</p>
<p>animations:^{ [[blueViewController view] removeFromSuperview]; [[ self view] insertSubview:yellowViewController.view atIndex:0]; }</p>
<p>completion: NULL];</p>
<p>写出上面代码的Block的定义。<br />
答:</p>
<p>typedef void(^animations) (void);</p>
<p>typedef void(^completion) (BOOL finished);</p>
<p>试着使用+ beginAnimations:context:以及上述Block的定义,写出一个可以完成</p>
<p>(void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void(^)(void))animations completion:(void(^)(BOOLfinished))completion NS_AVAILABLE_IOS(4_0);操作的函数执行部分</p>
<p>答案:无</p>
<h3><a id="%E5%81%9A%E8%BF%87%E7%9A%84%E9%A1%B9%E7%9B%AE%E6%98%AF%E5%90%A6%E6%B6%89%E5%8F%8A%E7%BD%91%E7%BB%9C%E8%AE%BF%E9%97%AE%E5%8A%9F%E8%83%BD%EF%BC%8C%E4%BD%BF%E7%94%A8%E4%BB%80%E4%B9%88%E5%AF%B9%E8%B1%A1%E5%AE%8C%E6%88%90%E7%BD%91%E7%BB%9C%E5%8A%9F%E8%83%BD" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>做过的项目是否涉及网络访问功能,使用什么对象完成网络功能?</h3>
<p>答:ASIHTTPRequest与NSURLConnection</p>
<p>简单介绍下NSURLConnection类及+ sendSynchronousRequest:returningResponse:error:与– initWithRequest:delegate:两个方法的区别?<br />
答: NSURLConnection主要用于网络访问,其中+ sendSynchronousRequest:returningResponse:error:是同步访问数据,即当前线程会阻塞,并等待request的返回的response,而– initWithRequest:delegate:使用的是异步加载,当其完成网络访问后,会通过delegate回到主线程,并其委托的对象。</p>
<h3><a id="%E5%A4%9A%E7%BA%BF%E7%A8%8B%E6%98%AF%E4%BB%80%E4%B9%88" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>多线程是什么</h3>
<p>答:多线程是个复杂的概念,按字面意思是同步完成多项任务,提高了资源的使用效率,从硬件、操作系统、应用软件不同的角度去看,多线程被赋予不同的内涵,对于硬件,现在市面上多数的CPU都是多核的,多核的CPU运算多线程更为出色;从操作系统角度,是多任务,现在用的主流操作系统都是多任务的,可以一边听歌、一边写博客;对于应用来说,多线程可以让应用有更快的回应,可以在网络下载时,同时响应用户的触摸操作。在iOS应用中,对多线程最初的理解,就是并发,它的含义是原来先做烧水,再摘菜,再炒菜的工作,会变成烧水的同时去摘菜,最后去炒菜。</p>
<h3><a id="ios%E4%B8%AD%E7%9A%84%E5%A4%9A%E7%BA%BF%E7%A8%8B" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>iOS中的多线程</h3>
<p>答: iOS中的多线程,是Cocoa框架下的多线程,通过Cocoa的封装,可以让我们更为方便的使用线程,做过C++的同学可能会对线程有更多的理解,比如线程的创立,信号量、共享变量有认识,Cocoa框架下会方便很多,它对线程做了封装,有些封装,可以让我们创建的对象,本身便拥有线程,也就是线程的对象化抽象,从而减少我们的工程,提供程序的健壮性。</p>
<p>GCD是(Grand Central Dispatch)的缩写 ,从系统级别提供的一个易用地多线程类库,具有运行时的特点,能充分利用多核心硬件。GCD的API接口为C语言的函数,函数参数中多数有Block,关于Block的使用参看这里,为我们提供强大的“接口”,对于GCD的使用参见本文</p>
<p>NSOperation与Queue</p>
<p>NSOperation是一个抽象类,它封装了线程的细节实现,我们可以通过子类化该对象,加上NSQueue来同面向对象的思维,管理多线程程序。具体可参看这里:一个基于NSOperation的多线程网络访问的项目。</p>
<p>NSThread</p>
<p>NSThread是一个控制线程执行的对象,它不如NSOperation抽象,通过它我们可以方便的得到一个线程,并控制它。但NSThread的线程之间的并发控制,是需要我们自己来控制的,可以通过NSCondition实现。</p>
<p>参看iOS多线程编程之NSThread的使用</p>
<p>其他多线程</p>
<p>在Cocoa的框架下,通知、Timer和异步函数等都有使用多线程,(待补充).</p>
<p>在项目什么时候选择使用GCD,什么时候选择NSOperation?<br />
答:项目中使用NSOperation的优点是NSOperation是对线程的高度抽象,在项目中使用它,会使项目的程序结构更好,子类化NSOperation的设计思路,是具有面向对象的优点(复用、封装),使得实现是多线程支持,而接口简单,建议在复杂项目中使用。</p>
<p>项目中使用GCD的优点是GCD本身非常简单、易用,对于不复杂的多线程操作,会节省代码量,而Block参数的使用,会是代码更为易读,建议在简单项目中使用。</p>
<h3><a id="%E4%BB%80%E4%B9%88%E6%98%AFblock" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>什么是block</h3>
<p>答:对于闭包(block),有很多定义,其中闭包就是能够读取其它函数内部变量的函数,这个定义即接近本质又较好理解。对于刚接触Block的同学,会觉得有些绕,因为我们习惯写这样的程序main(){ funA();} funA(){funB();} funB(){…..};就是函数main调用函数A,函数A调用函数B…函数们依次顺序执行,但现实中不全是这样的,例如项目经理M,手下有3个程序员A、B、C,当他给程序员A安排实现功能F1时,他并不等着A完成之后,再去安排B去实现F2,而是安排给A功能F1,B功能F2,C功能F3,然后可能去写技术文档,而当A遇到问题时,他会来找项目经理M,当B做完时,会通知M,这就是一个异步执行的例子。在这种情形下,Block便可大显身手,因为在项目经理M,给A安排工作时,同时会告诉A若果遇到困难,如何能找到他报告问题(例如打他手机号),这就是项目经理M给A的一个回调接口,要回掉的操作,比如接到电话,百度查询后,返回网页内容给A,这就是一个Block,在M交待工作时,已经定义好,并且取得了F1的任务号(局部变量),却是在当A遇到问题时,才调用执行,跨函数在项目经理M查询百度,获得结果后回调该block。</p>
<h3><a id="block%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>block实现原理</h3>
<p>答: Objective-C是对C语言的扩展,block的实现是基于指针和函数指针。</p>
<p>从计算语言的发展,最早的goto,高级语言的指针,到面向对象语言的block,从机器的思维,一步步接近人的思维,以方便开发人员更为高效、直接的描述出现实的逻辑(需求)。</p>
<p>使用实例</p>
<p>cocoaTouch框架下动画效果的Block的调用</p>
<p>使用typed声明block</p>
<p>typedef void(^didFinishBlock) (NSObject *ob);</p>
<p>这就声明了一个didFinishBlock类型的block,</p>
<p>然后便可用</p>
<p>@property (nonatomic,copy) didFinishBlock finishBlock;</p>
<p>声明一个blokc对象,注意对象属性设置为copy,接到block参数时,便会自动复制一份。</p>
<p>__block是一种特殊类型,</p>
<p>使用该关键字声明的局部变量,可以被block所改变,并且其在原函数中的值会被改变。</p>
<h3><a id="%E5%85%B3%E4%BA%8Eblock" class="anchor" aria-hidden="true"><span class="octicon octicon-link"></span></a>关于block</h3>
<p>答:面试时,面试官会先问一些,是否了解block,是否使用过block,这些问题相当于开场白,往往是下面一系列问题的开始,所以一定要如实根据自己的情况回答。</p>
<p>1).使用block和使用delegate完成委托模式有什么优点?</p>
<p>首先要了解什么是委托模式,委托模式在iOS中大量应用,其在设计模式中是适配器模式中的对象适配器,Objective-C中使用id类型指向一切对象,使委托模式更为简洁。了解委托模式的细节:</p>
<p>iOS设计模式—-委托模式</p>
<p>使用block实现委托模式,其优点是回调的block代码块定义在委托对象函数内部,使代码更为紧凑;</p>
<p>适配对象不再需要实现具体某个protocol,代码更为简洁。</p>
<p>2).多线程与block</p>
<p>GCD与Block</p>
<p>使用dispatch_async系列方法,可以以指定的方式执行block</p>
<p>GCD编程实例</p>
<p>dispatch_async的完整定义</p>
<p>void dispatch_async(</p>
<p>dispatch_queue_t queue,</p>
<p>dispatch_block_t block);</p>
<p>功能:在指定的队列里提交一个异步执行的block,不阻塞当前线程</p>
<p>通过queue来控制block执行的线程。主线程执行前文定义的finishBlock对象</p>
<p>dispatch_async(dispatch_get_main_queue(),^(void){finishBlock();});</p>
<p>62.谈谈Object-C的内存管理方式及过程?</p>
<p>答: 1).当你使用new,alloc和copy方法创建一个对象时,该对象的保留计数器值为1.当你不再使用该对象时,你要负责向该对象发送一条release或autorelease消息.这样,该对象将在使用寿命结束时被销毁.</p>
<p>2).当你通过任何其他方法获得一个对象时,则假设该对象的保留计数器值为1,而且已经被设置为自动释放,你不需要执行任何操作来确保该对象被清理.如果你打算在一段时间内拥有该对象,则需要保留它并确保在操作完成时释放它.</p>
<p>3).如果你保留了某个对象,你需要(最终)释放或自动释放该对象.必须保持retain方法和release方法的使用次数相等.</p>
<p>63.Object-C有私有方法吗?私有变量呢?</p>
<p>答: objective-c –类里面的方法只有两种,静态方法和实例方法.这似乎就不是完整的面向对象了,按照OO的原则就是一个对象只暴露有用的东西.如果没有了私有方法的话,对于一些小范围的代码重用就不那么顺手了.在类里面声名一个私有方法</p>
<p>@interface Controller : NSObject { NSString *something; }</p>
<p>(void)thisIsAStaticMethod;<br />
– (void)thisIsAnInstanceMethod;</p>
<p>@end</p>
<p>@interface Controller (private) -</p>
<p>(void)thisIsAPrivateMethod;</p>
<p>@end</p>
<p>@private可以用来修饰私有变量</p>
<p>在Objective‐C中,所有实例变量默认都是私有的,所有实例方法默认都是公有的</p>
<p>64.Object-C有多继承吗?没有的话用什么代替?cocoa中所有的类都是NSObject的子类</p>
<p>答:多继承在这里是用protocol委托代理 来实现的</p>
<p>你不用去考虑繁琐的多继承,虚基类的概念.</p>
<p>ood的多态特性 在obj-c中通过委托来实现.</p>
<p>65.内存管理Autorelease、retain、copy、assign的set方法和含义?</p>
<p>答: 1).你初始化(alloc/init)的对象,你需要释放(release)它。例如:</p>
<p>NSMutableArray aArray = [[NSArray alloc] init];后,需要[aArray release];</p>
<p>2).你retain或copy的,你需要释放它。例如:</p>
<p>[aArray retain]后,需要[aArray release];</p>
<p>3).被传递(assign)的对象,你需要斟酌的retain和release。例如:</p>
<p>obj2 = [[obj1 someMethod] autorelease];</p>
<p>对象2接收对象1的一个自动释放的值,或传递一个基本数据类型(NSInteger,NSString)时:你或希望将对象2进行retain,以防止它在被使用之前就被自动释放掉。但是在retain后,一定要在适当的时候进行释放。</p>
<p>关于索引计数(Reference Counting)的问题</p>
<p>retain值=索引计数(Reference Counting)</p>
<p>NSArray对象会retain(retain值加一)任何数组中的对象。当NSArray被卸载(dealloc)的时候,所有数组中的对象会 被 执行一次释放(retain值减一)。不仅仅是NSArray,任何收集类(Collection Classes)都执行类似操作。例如NSDictionary,甚至UINavigationController。</p>
<p>Alloc/init建立的对象,索引计数为1。无需将其再次retain。</p>
<p>[NSArray array]和[NSDate date]等“方法”建立一个索引计数为1的对象,但是也是一个自动释放对象。所以是本地临时对象,那么无所谓了。如果是打算在全Class中使用的变量(iVar),则必须retain它。</p>
<p>缺省的类方法返回值都被执行了“自动释放”方法。(*如上中的NSArray)</p>
<p>在类中的卸载方法“dealloc”中,release所有未被平衡的NS对象。(*所有未被autorelease,而retain值为1的)</p>
<p>C和obj-c如何混用<br />
答: 1).obj-c的编译器处理后缀为m的文件时,可以识别obj-c和c的代码,处理mm文件可以识别obj-c,c,c++代码,但cpp文件必须只能用c/c++代码,而且cpp文件include的头文件中,也不能出现obj-c的代码,因为cpp只是cpp</p>
<p>2).在mm文件中混用cpp直接使用即可,所以obj-c混cpp不是问题</p>
<p>3).在cpp中混用obj-c其实就是使用obj-c编写的模块是我们想要的。</p>
<p>如果模块以类实现,那么要按照cpp class的标准写类的定义,头文件中不能出现obj-c的东西,包括#import cocoa的。实现文件中,即类的实现代码中可以使用obj-c的东西,可以import,只是后缀是mm。</p>
<p>如果模块以函数实现,那么头文件要按c的格式声明函数,实现文件中,c++函数内部可以用obj-c,但后缀还是mm或m。</p>
<p>总结:只要cpp文件和cpp include的文件中不包含obj-c的东西就可以用了,cpp混用obj-c的关键是使用接口,而不能直接使用 实现代 码,实际上cpp混用的是obj-c编译后的o文件,这个东西其实是无差别的,所以可以用。obj-c的编译器支持cpp</p>
<p>Objective-C堆和栈的区别?<br />
答:管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak。</p>
<p>申请大小:</p>
<p>栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因 此,能从栈获得的空间较小。</p>
<p>堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。</p>
<p>碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出</p>
<p>分配方式:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。</p>
<p>分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的。</p>
<p>ViewController的didReceiveMemoryWarning怎么被调用:<br />
答:[supper didReceiveMemoryWarning];</p>
<p>69.什么时候用delegate,什么时候用Notification?</p>
<p>答: delegate针对one-to-one关系,用于sender接受到reciever的某个功能反馈值。</p>
<p>notification针对one-to-one/many/none,reciver,用于通知多个object某个事件。</p>
<p>70.用预处理指令#define声明一个常数,用以表明1年中有多少秒(忽略闰年问题)</p>
<p>答:</p>
<p>define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL</p>
<p>我在这想看到几件事情:</p>
<p>define语法的基本知识(例如:不能以分号结束,括号的使用,等等)</p>
<p>懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。</p>
<p>意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。</p>
<p>如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。记住,第一印象很重要。</p>
<p>71.写一个”标准"宏MIN,这个宏输入两个参数并返回较小的一个。</p>
<p>答:</p>
<p>define MIN(A,B)((A)<= (B) ? (A) : (B))</p>
<p>这个测试是为下面的目的而设的:</p>
<p>标识#define在宏中应用的基本知识。这是很重要的,因为直到嵌入(inline)操作符变为标准C的一部分,宏是方便产生嵌入代码的唯一方</p>
<p>法,</p>
<p>对于嵌入式系统来说,为了能达到要求的性能,嵌入代码经常是必须的方法。</p>
<p>三重条件操作符的知识。这个操作符存在C语言中的原因是它使得编译器能产生比if-then-else更优化的代码,了解这个用法是很重要的。</p>
<p>懂得在宏中小心地把参数用括号括起来</p>
<p>我也用这个问题开始讨论宏的副作用,例如:当你写下面的代码时会发生什么事?</p>
<p>least = MIN(*p++, b);</p>
<p>结果是:</p>
<p>((p++) <= (b) ? (p++) : (*p++))</p>
<p>这个表达式会产生副作用,指针p会作三次++自增操作。</p>
<p>72.关键字const有什么含意?修饰类呢?static的作用,用于类呢?还有externc的作用</p>
<p>答:</p>
<p>const意味着"只读",下面的声明都是什么意思?</p>
<p>const inta;</p>
<p>int consta;</p>
<p>const int*a;</p>
<p>int*consta;</p>
<p>int const* aconst;</p>
<p>前两个的作用是一样,a是一个常整型数。</p>
<p>第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。</p>
<p>第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。</p>
<p>最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。</p>
<p>结论:</p>
<p>关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。</p>
<p>如果你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(当然,懂得用const的程序员很少会留下的垃圾让别人来清理的) 通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。</p>
<p>1).欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初</p>
<p>始化,因为以后就没有机会再去改变它了;</p>
<p>2).对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指</p>
<p>定为const;</p>
<p>3).在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;</p>
<p>4).对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;</p>
<p>5).对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。</p>
<p>关键字volatile有什么含意?并给出三个不同的例子。<br />
答:一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。</p>
<p>下面是volatile变量的几个例子:</p>
<p>并行设备的硬件寄存器(如:状态寄存器)</p>
<p>一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)</p>
<p>多线程应用中被几个任务共享的变量</p>
<p>一个参数既可以是const还可以是volatile吗? 一个指针可以是volatile吗?解释为什么。<br />
答:1).是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。</p>
<p>2).是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。</p>
<p>75 .static关键字的作用:</p>
<p>答:</p>
<p>1).函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,</p>
<p>因此其值在下次调用时仍维持上次的值;</p>
<p>2).在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;</p>
<p>3).在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明</p>
<p>它的模块内;</p>
<p>4).在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;</p>
<p>5).在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。</p>
<p>线程与进程的区别和联系?<br />
答:</p>
<p>1).进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性</p>
<p>2).进程和线程的主要差别在于它们是不同的操作系统资源管理方式。</p>
<p>3).进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。</p>
<p>4.)线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉。所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。</p>
<p>5).但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。</p>
<p>列举几种进程的同步机制,并比较其优缺点。<br />
答: 原子操作 信号量机制 自旋锁 管程,会合,分布式系统</p>
<p>进程之间通信的途径<br />
答:共享存储系统消息传递系统管道:以文件系统为基础</p>
<p>进程死锁的原因<br />
答:资源竞争及进程推进顺序非法</p>
<p>死锁的4个必要条件<br />
答:互斥、请求保持、不可剥夺、环路</p>
<p>死锁的处理<br />
答:鸵鸟策略、预防策略、避免策略、检测与解除死锁</p>
<p>cocoa touch框架<br />
答:iPhone OS应用程序的基础Cocoa Touch框架重用了许多Mac系统的成熟模式,但是它更多地专注于触摸的接口和优化。</p>
<p>UIKit为您提供了在iPhone OS上实现图形,事件驱动程序的基本工具,其建立在和Mac OS X中一样的Foundation框架上,包括文件处理,网络,字符串操作等。</p>
<p>Cocoa Touch具有和iPhone用户接口一致的特殊设计。有了UIKit,您可以使用iPhone OS上的独特的图形接口控件,按钮,以及全屏视图的功能,您还可以使用加速仪和多点触摸手势来控制您的应用。</p>
<p>各色俱全的框架 除了UIKit外,Cocoa Touch包含了创建世界一流iPhone应用程序需要的所有框架,从三维图形,到专业音效,甚至提供设备访问API以控制摄像头,或通过GPS获知当前位置。</p>
<p>Cocoa Touch既包含只需要几行代码就可以完成全部任务的强大的Objective-C框架,也在需要时提供基础的C语言API来直接访问系统。这些框架包括:</p>
<p>Core Animation:通过Core Animation,您就可以通过一个基于组合独立图层的简单的编程模型来创建丰富的用户体验。</p>
<p>Core Audio:Core Audio是播放,处理和录制音频的专业技术,能够轻松为您的应用程序添加强大的音频功能。</p>
<p>Core Data:提供了一个面向对象的数据管理解决方案,它易于使用和理解,甚至可处理任何应用或大或小的数据模型。</p>
<p>功能列表:框架分类</p>
<p>下面是Cocoa Touch中一小部分可用的框架:</p>
<p>音频和视频:Core Audio,OpenAL,Media Library,AV Foundation</p>
<p>数据管理 :Core Data,SQLite</p>
<p>图形和动画 :Core Animation,OpenGL ES,Quartz 2D</p>
<p>网络:Bonjour,WebKit,BSD Sockets</p>
<p>用户应用:Address Book,Core Location,Map Kit,Store Kit</p>
<p>自动释放池是什么,如何工作<br />
答:当您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放.它仍然是个正当的对象,因此自动释放池定义的作用域内的其它对象可以向它发送消息。当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放。</p>
<p>Objective-C的优缺点。<br />
答:objc优点:</p>
<p>1). Cateogies</p>
<p>2). Posing</p>
<p>3).动态识别</p>
<p>4).指标计算</p>
<p>5).弹性讯息传递</p>
<p>6).不是一个过度复杂的C衍生语言</p>
<p>7).Objective-C与C++可混合编程</p>
<p>objc缺点:</p>
<p>1).不支援命名空间</p>
<p>2).不支持运算符重载</p>
<p>3).不支持多重继承</p>
<p>4).使用动态运行时类型,所有的方法都是函数调用,所以很多编译时优化方法都用不到。(如内联函数等),性能低劣。</p>
<p>sprintf,strcpy,memcpy使用上有什么要注意的地方。<br />
答:</p>
<p>1). sprintf是格式化函数。将一段数据通过特定的格式,格式化到一个字符串缓冲区中去。sprintf格式化的函数的长度不可控,有可能格式化后的字符串会超出缓冲区的大小,造成溢出。</p>
<p>2).strcpy是一个字符串拷贝的函数,它的函数原型为strcpy(chardst,const charsrc将src开始的一段字符串拷贝到dst开始的内存中去,结束的标志符号为‘\0',由于拷贝的长度不是由我们自己控制的,所以这个字符串拷贝很容易出错。</p>
<p>3). memcpy是具备字符串拷贝功能的函数,这是一个内存拷贝函数,它的函数原型为memcpy(chardst,const charsrc,unsigned intlen);将长度为len的一段内存,从src拷贝到dst中去,这个函数的长度可控。但是会有内存叠加的问题。</p>
<p>readwrite,readonly,assign,retain,copy,nonatomic属性的作用<br />
答:@property是一个属性访问声明,扩号内支持以下几个属性:</p>
<p>1).getter=getterName,setter=setterName,设置setter与getter的方法名</p>
<p>2).readwrite,readonly,设置可供访问级别</p>
<p>2).assign,setter方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题</p>
<p>3).retain,setter方法对参数进行release旧值再retain新值,所有实现都是这个顺序(CC上有相关资料)</p>
<p>4).copy,setter方法进行Copy操作,与retain处理流程一样,先旧值release,再Copy出新的对象,retainCount为1。这是为了减少对上下文的依赖而引入的机制。</p>
<p>5).nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级。</p>
<p>http和scoket通信的区别。<br />
答:http是客户端用http协议进行请求,发送请求时候需要封装http请求头,并绑定请求的数据,服务器一般有web服务器配合(当然也非绝对)。http请求方式为客户端主动发起请求,服务器才能给响应,一次请求完毕后则断开连接,以节省资源。服务器不能主动给客户端响应(除非采取http长连接 技术)。iphone主要使用类是NSUrlConnection。</p>
<p>scoket是客户端跟服务器直接使用socket“套接字”进行连接,并没有规定连接后断开,所以客户端和服务器可以保持连接通道,双方 都可以主动发送数据。一般在游戏开发或股票开发这种要求即时性很强并且保持发送数据量比较大的场合使用。主要使用类是CFSocketRef。</p>
<p>TCP和UDP的区别<br />
答:TCP全称是Transmission Control Protocol,中文名为传输控制协议,它可以提供可靠的、面向连接的网络数据传递服务。传输控制协议主要包含下列任务和功能:</p>
<p>确保IP数据报的成功传递。</p>
<p>对程序发送的大块数据进行分段和重组。</p>
<p>确保正确排序及按顺序传递分段的数据。</p>
<p>通过计算校验和,进行传输数据的完整性检查。</p>
<p>TCP提供的是面向连接的、可靠的数据流传输,而UDP提供的是非面向连接的、不可靠的数据流传输。</p>
<p>简单的说,TCP注重数据安全,而UDP数据传输快点,但安全性一般</p>
<p>你了解svn,cvs等版本控制工具么?<br />
答: 版本控制svn,cvs是两种版控制的器,需要配套相关的svn,cvs服务器。</p>
<p>scm是xcode里配置版本控制的地方。版本控制的原理就是a和b同时开发一个项目,a写完当天的代码之后把代码提交给服务器,b要做的时候先从服务器得到最新版本,就可以接着做。 如果a和b都要提交给服务器,并且同时修改了同一个方法,就会产生代码冲突,如果a先提交,那么b提交时,服务器可以提示冲突的代码,b可以清晰的看到,并做出相应的修改或融合后再提交到服务器。</p>
<p>什么是push。<br />
答: 客户端程序留下后门端口,客户端总是监听针对这个后门的请求,于是 服务器可以主动像这个端口推送消息。</p>
<p>静态链接库<br />
答:此为.a文件,相当于java里的jar包,把一些类编译到一个包中,在不同的工程中如果导入此文件就可以使用里面的类,具体使用依然是#import “ xx.h”。</p>
<p>fmmpeg框架<br />
答: 音视频编解码框架,内部使用UDP协议针对流媒体开发,内部开辟了六个端口来接受流媒体数据,完成快速接受之目的。</p>
<p>fmdb框架<br />
答:数据库框架,对sqllite的数据操作进行了封装,使用着可把精力都放在sql语句上面。</p>
<p>320框架<br />
答:ui框架,导入320工程作为框架包如同添加一个普通框架一样。cover(open) flower框架(2d仿射技术),内部核心类是CATransform3D.</p>
<p>什么是沙盒模型?哪些操作是属于私有api范畴?<br />
答:某个iphone工程进行文件操作有此工程对应的指定的位置,不能逾越。</p>
<p>iphone沙箱模型的有四个文件夹documents,tmp,app,Library,永久数据存储一般放documents文件夹,得到模拟器的路径的可使用NSHomeDirectory()方法。Nsuserdefaults保存的文件在tmp文件夹里。</p>
<p>在一个对象的方法里面:self.name= “object”;和name =”object”有什么不同吗?<br />
答:self.name =”object”:会调用对象的setName()方法;</p>
<p>name = “object”:会直接把object赋值给当前对象的name属性。</p>
<p>请简要说明viewDidLoad和viewDidUnload何时调用<br />
答:viewDidLoad在view从nib文件初始化时调用,loadView在controller的view为nil时调用。此方法在编程实现view时调用,view控制器默认会注册memory warning notification,当view controller的任何view没有用的时候,viewDidUnload会被调用,在这里实现将retain的view release,如果是retain的IBOutletview属性则不要在这里release,IBOutlet会负责release。</p>
<p>简述内存分区情况<br />
答:</p>
<p>1).代码区:存放函数二进制代码</p>
<p>2).数据区:系统运行时申请内存并初始化,系统退出时由系统释放。存放全局变量、静态变量、常量</p>
<p>3).堆区:通过malloc等函数或new等操作符动态申请得到,需程序员手动申请和释放</p>
<p>4).栈区:函数模块内申请,函数结束时由系统自动释放。存放局部变量、函数参数</p>
<p>队列和栈有什么区别:<br />
答:队列和栈是两种不同的数据容器。从”数据结构”的角度看,它们都是线性结构,即数据元素之间的关系相同。</p>
<p>队列是一种先进先出的数据结构,它在两端进行操作,一端进行入队列操作,一端进行出列队操作。</p>
<p>栈是一种先进后出的数据结构,它只能在栈顶进行操作,入栈和出栈都在栈顶操作。</p>
<p>HTTP协议中,POST和GET的区别是什么?<br />
答:</p>
<p>1).GET方法</p>
<p>GET方法提交数据不安全,数据置于请求行,客户端地址栏可见;</p>
<p>GET方法提交的数据大小有限</p>
<p>GET方法不可以设置书签</p>
<p>2).POST方法</p>
<p>POST方法提交数据安全,数据置于消息主体内,客户端不可见</p>
<p>POST方法提交的数据大小没有限制</p>
<p>POST方法可以设置书签</p>
<p>iOS的系统架构<br />
答:iOS的系统架构分为( 核心操作系统层theCore OS layer)、( 核心服务层theCore Services layer)、( 媒体层theMedia layer)和(Cocoa界面服务层the Cocoa Touch layer)四个层次。</p>
<p>控件主要响应3种事件<br />
答:1).基于触摸的事件; 2).基于值的事件; 3).基于编辑的事件。</p>
<p>xib文件的构成分为哪3个图标?都具有什么功能。<br />
答:File’s Owner是所有nib文件中的每个图标,它表示从磁盘加载nib文件的对象;</p>
<p>First Responder就是用户当前正在与之交互的对象;</p>
<p>View显示用户界面;完成用户交互;是UIView类或其子类。</p>
<p>简述视图控件器的生命周期。<br />
答:loadView尽管不直接调用该方法,如多手动创建自己的视图,那么应该覆盖这个方法并将它们赋值给试图控制器的view属性。</p>
<p>viewDidLoad只有在视图控制器将其视图载入到内存之后才调用该方法,这是执行任何其他初始化操作的入口。</p>
<p>viewDidUnload当试图控制器从内存释放自己的方法的时候调用,用于清楚那些可能已经在试图控制器中创建的对象。</p>
<p>viewVillAppear当试图将要添加到窗口中并且还不可见的时候或者上层视图移出图层后本视图变成顶级视图时调用该方法,用于执行诸如改变视图方向等的操作。实现该方法时确保调用[superviewWillAppear:<br />
viewDidAppear当视图添加到窗口中以后或者上层视图移出图层后本视图变成顶级视图时调用,用于放置那些需要在视图显示后执行的代码。确保调用[superviewDidAppear:]。</p>
<p>动画有基本类型有哪几种;表视图有哪几种基本样式。<br />
答:动画有两种基本类型:隐式动画和显式动画。</p>
<p>实现简单的表格显示需要设置UITableView的什么属性、实现什么协议?<br />
答:实现简单的表格显示需要设置UITableView的dataSource和delegate属性,实现UITableViewDataSource和UITableViewDelegate协议。</p>
<p>Cocoa Touch提供了哪几种Core Animation过渡类型?<br />
答:Cocoa Touch提供了4种Core Animation过渡类型,分别为:交叉淡化、推挤、显示和覆盖。</p>
<p>UIView与CLayer有什么区别?<br />
答:</p>
<p>1).UIView是iOS系统中界面元素的基础,所有的界面元素都是继承自它。它本身完全是由CoreAnimation来实现的。它真正的绘图部分,是由一个CALayer类来管理。UIView本身更像是一个CALayer的管理器,访问它的跟绘图和跟坐标有关的属性。</p>
<p>2).UIView有个重要属性layer,可以返回它的主CALayer实例。</p>
<p>3).UIView的CALayer类似UIView的子View树形结构,也可以向它的layer上添加子layer,来完成某些特殊的表示。即CALayer层是可以嵌套的。</p>
<p>4).UIView的layer树形在系统内部,被维护着三份copy。分别是逻辑树,这里是代码可以操纵的;动画树,是一个中间层,系统就在这一层上更改属性,进行各种渲染操作;显示树,其内容就是当前正被显示在屏幕上得内容。</p>
<p>5).动画的运作:对UIView的subLayer(非主Layer)属性进行更改,系统将自动进行动画生成,动画持续时间的缺省值似乎是0.5秒。</p>
<p>6).坐标系统:CALayer的坐标系统比UIView多了一个anchorPoint属性,使用CGPoint结构表示,值域是0~1,是个比例值。这个点是各种图形变换的坐标原点,同时会更改layer的position的位置,它的缺省值是{0.5,0.5},即在layer的中央。</p>
<p>7).渲染:当更新层,改变不能立即显示在屏幕上。当所有的层都准备好时,可以调用setNeedsDisplay方法来重绘显示。</p>
<p>8).变换:要在一个层中添加一个3D或仿射变换,可以分别设置层的transform或affineTransform属性。</p>
<p>9).变形:Quartz Core的渲染能力,使二维图像可以被自由操纵,就好像是三维的。图像可以在一个三维坐标系中以任意角度被旋转,缩放和倾斜。CATransform3D的一套方法提供了一些魔术般的变换效果。</p>
<p>Quatrz 2D的绘图功能的三个核心概念是什么并简述其作用。<br />
答:上下文:主要用于描述图形写入哪里;</p>
<p>路径:是在图层上绘制的内容;</p>
<p>状态:用于保存配置变换的值、填充和轮廓,alpha值等。</p>
<p>iPhone OS主要提供了几种播放音频的方法?<br />
答:SystemSound Services</p>
<p>AVAudioPlayer类</p>
<p>Audio Queue Services</p>
<p>OpenAL</p>
<p>使用AVAudioPlayer类调用哪个框架、使用步骤?<br />
答:AVFoundation.framework</p>
<p>步骤:配置AVAudioPlayer对象;</p>
<p>实现AVAudioPlayer类的委托方法;</p>
<p>控制AVAudioPlayer类的对象;</p>
<p>监控音量水平;</p>
<p>回放进度和拖拽播放。</p>
<p>有哪几种手势通知方法、写清楚方法名?<br />
答:</p>
<p>-(void)touchesBegan:(NSSet)touchedwithEvent:(UIEvent)event;</p>
<p>-(void)touchesMoved:(NSSet)touched withEvent:(UIEvent)event;</p>
<p>-(void)touchesEnded:(NSSet)touchedwithEvent:(UIEvent)event;</p>
<p>-(void)touchesCanceled:(NSSet)touchedwithEvent:(UIEvent)event;</p>
<p>CFSocket使用有哪几个步骤。<br />
答:创建Socket的上下文;创建Socket;配置要访问的服务器信息;封装服务器信息;连接服务器;</p>
<p>Core Foundation中提供了哪几种操作Socket的方法?<br />
答:CFNetwork、CFSocket和BSD Socket。</p>
<p>解析XML文件有哪几种方式?<br />
答:以DOM方式解析XML文件;以SAX方式解析XML文件;</p>
<p>ios平台怎么做数据的持久化?coredata和sqlite有无必然联系?coredata是一个关系型数据库吗?<br />
答:iOS中可以有四种持久化数据的方式:属性列表(plist)、对象归档、SQLite3和Core Data;core data可以使你以图形界面的方式快速的定义app的数据模型,同时在你的代码中容易获取到它。coredata提供了基础结构去处理常用的功能,例如保存,恢复,撤销和重做,允许你在app中继续创建新的任务。在使用core data的时候,你不用安装额外的数据库系统,因为core data使用内置的sqlite数据库。core data将你app的模型层放入到一组定义在内存中的数据对象。coredata会追踪这些对象的改变,同时可以根据需要做相反的改变,例如用户执行撤销命令。当core data在对你app数据的改变进行保存的时候,core data会把这些数据归档,并永久性保存。mac os x中sqlite库,它是一个轻量级功能强大的关系数据引擎,也很容易嵌入到应用程序。可以在多个平台使用,sqlite是一个轻量级的嵌入式sql数据库编程。与core data框架不同的是,sqlite是使用程序式的,sql的主要的API来直接操作数据表。Core Data不是一个关系型数据库,也不是关系型数据库管理系统(RDBMS)。虽然Core Dta支持SQLite作为一种存储类型,但它不能使用任意的SQLite数据库。Core Data在使用的过程种自己创建这个数据库。Core Data支持对一、对多的关系。</p>
<p>tableView的重用机制?<br />
答:UITableView通过重用单元格来达到节省内存的目的:通过为每个单元格指定一个重用标识符(reuseIdentifier),即指定了单元格的种类,以及当单元格滚出屏幕时,允许恢复单元格以便重用.对于不同种类的单元格使用不同的ID,对于简单的表格,一个标识符就够了.</p>
<p>#父类实现深拷贝时,子类如何实现深度拷贝。父类没有实现深拷贝时,子类如何实现深度拷贝。<br />
•深拷贝同浅拷贝的区别:浅拷贝是指针拷贝,对一个对象进行浅拷贝,相当于对指向对象的指针进行复制,产生一个新的指向这个对象的指针,那么就是有两 个指针指向同一个对象,这个对象销毁后两个指针都应该置空。深拷贝是对一个对象进行拷贝,相当于对对象进行复制,产生一个新的对象,那么就有两个指针分别 指向两个对象。当一个对象改变或者被销毁后拷贝出来的新的对象不受影响。<br />
•实现深拷贝需要实现NSCoying协议,实现- (id)copyWithZone:(NSZone *)zone方法。当对一个property属性含有copy修饰符的时候,在进行赋值操作的时候实际上就是调用这个方法。<br />
•父类实现深拷贝之后,子类只要重写copyWithZone方法,在方法内部调用父类的copyWithZone方法,之后实现自己的属性的处理<br />
•父类没有实现深拷贝,子类除了需要对自己的属性进行处理,还要对父类的属性进行处理。<br />
#KVO,NSNotification,delegate及block区别<br />
• KVO就是cocoa框架实现的观察者模式,一般同KVC搭配使用,通过KVO可以监测一个值的变化,比如View的高度变化。是一对多的关系,一个值的变化会通知所有的观察者。<br />
• NSNotification是通知,也是一对多的使用场景。在某些情况下,KVO和NSNotification是一样的,都是状态变化之后告知 对方。NSNotification的特点,就是需要被观察者先主动发出通知,然后观察者注册监听后再来进行响应,比KVO多了发送通知的一步,但是其优 点是监听不局限于属性的变化,还可以对多种多样的状态变化进行监听,监听范围广,使用也更灵活。<br />
• delegate是代理,就是我不想做的事情交给别人做。比如狗需要吃饭,就通过delegate通知主人,主人就会给他做饭、盛饭、倒水,这些操作,这些狗都不需要关 心,只需要调用delegate(代理人)就可以了,由其他类完成所需要的操作。所以delegate是一对一关系。<br />
• block是delegate的另一种形式,是函数式编程的一种形式。使用场景跟delegate一样,相比delegate更灵活,而且代理的实现更直观。<br />
• KVO一般的使用场景是数据,需求是数据变化,比如股票价格变化,我们一般使用KVO(观察者模式)。delegate一般的使用场景是行为,需求是需要别人帮我做一件事情,比如买卖股票,我们一般使用delegate。<br />
Notification一般是进行全局通知,比如利好消息一出,通知大家去买入。delegate是强关联,就是委托和代理双方互相知道,你委托别人买股票你就需要知道经纪人, 经纪人也不要知道自己的顾客。Notification是弱关联,利好消息发出,你不需要知道是谁发的也可以做出相应的反应,同理发消息的人也不需要知道 接收的人也可以正常发出消息。<br />
#KVC如果实现,如何进行键值查找。KVO如何实现<br />
请看这两篇博文 KVC KVO<br />
#将一个函数在主线程执行的4种方法<br />
• GCD方法,通过向主线程队列发送一个block块,使block里的方法可以在主线程中执行。<br />
dispatch_async(dispatch_get_main_queue(), ^{<br />
//需要执行的方法<br />
});<br />
• NSOperation方法<br />
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue]; //主队列<br />
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{<br />
//需要执行的方法<br />
}];<br />
[mainQueue addOperation:operation];<br />
• NSThread方法<br />
[self performSelector:@selector(method) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES modes:nil];<br />
[self performSelectorOnMainThread:@selector(method) withObject:nil waitUntilDone:YES];<br />
[[NSThread mainThread] performSelector:@selector(method) withObject:nil];<br />
• RunLoop方法<br />
[[NSRunLoop mainRunLoop] performSelector:@selector(method) withObject:nil];<br />
#如何让计时器调用一个类方法<br />
•计时器只能调用实例方法,但是可以在这个实例方法里面调用静态方法。<br />
•使用计时器需要注意,计时器一定要加入RunLoop中,并且选好model才能运行。scheduledTimerWithTimeInterval方法创建一个计时器并加入到RunLoop中所以可以直接使用。<br />
•如果计时器的repeats选择YES说明这个计时器会重复执行,一定要在合适的时机调用计时器的invalid。不能在dealloc中调用, 因为一旦设置为repeats为yes,计时器会强持有self,导致dealloc永远不会被调用,这个类就永远无法被释放。比如可以在viewDidDisappear中调用,这 样当类需要被回收的时候就可以正常进入dealloc中了。<br />
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];<br />
-(void)timerMethod<br />
{<br />
//调用类方法<br />
[[ self class] staticMethod];<br />
}<br />
-(void)invalid<br />
{<br />
[timer invalid];<br />
timer = nil;<br />
}<br />
#如何重写类方法<br />
• 1、在子类中实现一个同基类名字一样的静态方法<br />
• 2、在调用的时候不要使用类名调用,而是使用[self class]的方式调用。原理,用类名调用是早绑定,在编译期绑定,用[self class]是晚绑定,在运行时决定调用哪个方法。<br />
#NSTimer创建后,会在哪个线程运行。<br />
•用scheduledTimerWithTimeInterval创建的,在哪个线程创建就会被加入哪个线程的RunLoop中就运行在哪个线程<br />
•自己创建的Timer,加入到哪个线程的RunLoop中就运行在哪个线程。<br />
#1.8id和NSObject*的区别<br />
•id是一个objc_object结构体指针,定义是<br />
typedef struct objc_object *id<br />
•id可以理解为指向对象的指针。所有oc的对象id都可以指向,编译器不会做类型检查,id调用任何存在的方法都不会在编译阶段报错,当然如果这个id指向的对象没有这个方法,该崩溃还是会崩溃的。<br />
• NSObject *指向的必须是NSObject的子类,调用的也只能是NSObjec里面的方法否则就要做强制类型转换。<br />
•不是所有的OC对象都是NSObject的子类,还有一些继承自NSProxy。NSObject *可指向的类型是id的子集。<br />
以下内容后续补充<br />
#iOS核心框架<br />
• CoreAnimation<br />
• CoreGraphics<br />
• CoreLocation<br />
• AVFoundation<br />
• Foundation<br />
#iOS核心机制<br />
• UITableView重用<br />
• ObjC内存管理;自动释放池,ARC如何实现<br />
• runloop<br />
• runtime<br />
• Block的定义、特性、内存区域、如何实现<br />
• Responder Chain<br />
• NSOperation<br />
#• GCD<br />
#数据结构<br />
• 8大排序算法<br />
•二叉树实现<br />
•二分查找实现<br />
#面向对象编程<br />
•封装、继承、多态<br />
•设计模式6个原则<br />
•设计一个类的功能,如何划分粒度(单一职责)<br />
•接口隔离。<br />
•如果有一个鸟类,有飞的动作,一个鸵鸟继承它是合适的吗(里氏替换)<br />
•类之间的依赖如何依赖偶合度最小(依赖倒转)<br />
高层依赖低层,低层不能依赖高层。依赖接口,不能依赖具体的类。<br />
•如果A要调用C函数,但C是B的成员类,应该如何设计?(迪米特)<br />
•如何设计类,能做到只增加代码,而不修改代码,有哪些经验(开放封闭)<br />
通过设计模式解决。<br />
#计算机技术<br />
•计算机网络:TCP/IP、HTTPCDN、SPDY<br />
•计算机安全:RSA、AES、DES<br />
•操作系统:线程、进程、堆栈、死锁、调度算法<br />
#iOS新特性、新技术<br />
• iOS7 UIDynamic、SpritKit、新布局、扁平化<br />
• iOS8应用程序扩展、HealthKit、SceneKit、CoreLocation、TouchID、PhotoKit<br />
• iOS9<br />
• Apple Watch<br />
#•第三方库:SDWebImage、AFNetwork、JSONKit、wax<br />
• swift</p>
<p>#****************************************************************************</p>
<p>#1.简述OC中内存管理机制.</p>
<p>答:内存管理机制:使用引用计数管理,分为ARC和MRC,MRC需要程序员自己管理内存,ARC则不需要.但是并不是所有对象在ARC环境下均不需要管理内存,子线程和循环引用并不是这样.与retain配对使用的是release,retain代表引用计数+1,release代表引用计数-1,当引用计数减为0时,对象则被系统自动销毁.与alloc配对使用的是dealloc,alloc代表为对象开辟内存空间,dealloc则代表销毁对象的内存空间.</p>
<p>#2.readwrite,readonly,assign,retain,copy,nonatomic,atomic,strong,weak的作用?</p>
<p>答:读写属性:readonly和readwrite; 语义属性:assign/retain/copy; 原子性:nonatomic.</p>
<p>①.readwrite代表可读,可写,即有setter和getter方法,是默认属性.readonly代表只可读,即只有get方法,因为不会生成setter方法,所以它不可以和copy/retain/assign组合使用.</p>
<p>②.weak和assign均是弱引用,assign修饰基本数据类型,weak修饰对象类型.strong和weak用于ARC下(ARC下的代理使用weak,block块使用copy).strong相当于retain.weak相当于assign;assign/retain/copy这些属性用于指定set访问器的语义,也就是说,这些属性决定了以何种方式对数据成员赋值.</p>
<p>assign,直接赋值,引用计数不改变,适用于基本数据类型.</p>
<p>retain,浅拷贝,使用的是原来的内存空间,只能适用于Objective-C对象类型,而不能适用于Core Foundation对象(retain会增加对象的引用计数,而基本数据和Core Foundation对象都没有引用计数).</p>
<p>copy:对象的拷贝,新申请一块内存空间,并把原始内容复制到那片空间.新对象的引用计数为1,此属性只对那些遵循了NSCopy协议的对象类型有效.</p>
<p>③.nonatomic,非原子性访问,不加同步,是异步操作.默认为atomic,原子操作,atomic是Objc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误,而这种机制是消耗系统内存资源的,所以在移动端,都选择nonatomic.</p>
<p>#另:内存分为5个区,分别是栈区,堆区,全局区,文字常量区,程序代码区.</p>
<p>栈区:由编译器自动分配释放,不需要管理内存.</p>
<p>堆区:一般有程序员分配释放.</p>
<p>全局区:存放全局变量和静态变量.</p>
<p>文字常量区:存放常量字符串.</p>
<p>程序代码区:存放二进制代码.</p>
<p>#3.类变量的@protected,@private,@public,@package,声明各有什么含义?</p>
<p>@protected受保护的.本类,子类可见.</p>
<p>@private私有的,类内可用</p>
<p>@public公有的,类内,子类,外部均可用</p>
<p>@package可见度在@protected和@public之间,这个类型最常用于框架类的实例变量.</p>
<p>#4.线程是什么?进程又是什么?区别和联系.</p>
<p>进程:正在运行的程序,负责程序的内存分配.</p>
<p>线程:线程是进程中一个独立执行的控制单元(路径),一个进程至少包含一条线程,即主线程.</p>
<p>创建线程的目的:开辟一条新的执行路径,运行指定的代码,与主线程的代码实现同时执行.</p>
<p>#5.对多线程开发的理解,iOS中有几种实现多线程的方式.</p>
<p>多线程的使用场景:防止卡顿,可以同时完成多个任务,且不影响主线程,把耗时操作放在子线程中执行,但是会消耗内存.</p>
<p>实现多线程的方式:①.NSThread(内存需要自己管理.触发),②.NSOperationQueue(不再关注线程,当前可执行任务个数queue.maxConcurrentOperationCount)③.GCD</p>
<p>#详解三种实现多线程的方式:<br />
GCD:</p>
<p>GCD里面包含了串行队列、并行队列、主队列、全局队列。</p>
<p>Dispatch_queue_t q = dispatch_queue_create(“qqq”,DISPATCH_QUEUE_SERIAL);//创建一个串行队列</p>
<p>Dispatch_sync(q,^{</p>
<p>});//开启同步任务</p>
<p>Dispatch_async(q,^{</p>
<p>});//开启异步任务</p>
<p>并行队列:DISPATCH_QUEUE_CONCURRENT</p>
<p>主队列:dispatch_queue_t q = dispatch_get_main_queue();</p>
<p>全局队列:dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);<br />
NSThread</p>
<p>获取当前线程:NSThread * current = [NSThread currentThread];</p>
<p>获取主线程:NSThread * main = [NSThread mainThread];</p>
<p>使用NSThread创建线程的两种方式:</p>
<ul>
<li>(id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;</li>
</ul>
<ul>
<li>(void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;</li>
</ul>
<p>暂停当前线程:</p>
<p>[NSThread sleepForTimeInterval:2];<br />
NSOperationQueue</p>
<p>创建一个操作队列:NSOperationQueue * queue = [[NSOperationQueue alloc]init];</p>
<p>添加NSOperation到NSOperationQueue中:[queue addOperation:operation];</p>
<p>添加一组operation:[queue addOperations:operations waitUntilFinished:NO];</p>
<p>添加一个block形式的operation:[queue addOperationWithBlock:^(){</p>
<p>}];</p>
<p>添加NSOperation的依赖对象:[operation2 addDependency:operation1];</p>
<p>设置队列的最大操作数:[queue setMaxConcurrentOperationCount:1];</p>
<p>等待options完成:[operation waitUntilFinished];</p>
<p>暂停、继续queue:[queue setSuspended:YES] [queue setSuspend:NO]</p>
<p>#6.线程同步和异步的区别?ios中如何实现线程的同步?</p>
<p>同步:任务顺序执行,下一个任务依赖于上一任务的完成.</p>
<p>异步:任务执行顺序不定,一起执行.</p>
<p>实现:设置依赖:NSOpreationQueue GCD中的串行队列.</p>
<p>#7.iOS类是否可以多继承,如果没有,怎么实现?</p>
<p>不可以多继承.</p>
<p>可以通过类目,延展,协议实现多继承.</p>
<p>类目:类目也叫分类,英文category,在没有原类.m文件的基础上,给该类添加方法.类目里不能添加实例变量,不能添加和原始类方法名相同的方法,否则会发生覆盖.一个类可以添加多个类目,类目中的方法可以成为原始类的一部分,和原始类方法级别相同,可以被子类继承.</p>
<p>延展:Extension,是一种特殊形式的类目,主要是在一个类的.m里面声明与实现.作用:就是给某类添加私有方法或者私有变量.</p>
<p>虽然延展是给一个类定义私有方法,但是OC没有绝对的私有方法,其实还是可以调用的,延展里面声明的变量只能在该类内部使用,外界访问不了.如果是新建文件建的的某类延展.h文件,则不能添加实例变量,如果括号里没有类目名,则认为延展里面的方法为全都必须实现,如果有,则可选实现.</p>
<p>类目写的方法必须实现,延展写的方法非必须.</p>
<p>#8.栈和堆的区别?</p>
<p>栈:内存系统管理(系统开辟,系统释放),先进后出.</p>
<p>堆:内存自己管理(自己开辟,自己释放).先进先出.</p>
<p>#9.iOS本地数据存储都有几种方式?</p>
<p>①.NSkeyedArchiver:采用归档的形式来保存数据,该数据对象需要遵守NSCoding协议,并且该对象对应的类必须提供encodeWithCoder:和initWithCoder:方法.前一个方法告诉系统怎么对对象进行编码,而后一个方法则是告诉系统怎么对对象进行解码.</p>
<p>②.NSUserDefaults:用来保存应用程序设置和属性,用户保存的数据.用户再次打开程序或者开机后这些数据仍然存在.NSUserDefaults可以存储的数据类型包括:NSData,NSString,NSNumber,NSDate,NSArray.NSDictionary,其他类型的数据需要先行转换.</p>
<p>③.Write写入方式:永久保存在磁盘中.具体:a.获得文件保存的路径.b.生成该路径下的文件,c,往文件中写入数据.d.从文件中读出数据.</p>
<p>④.SQLite:采用SQLite数据库来存储数据,SQLite作为一种轻量级数据库.具体:a.添加SQLite相关的库以及头文件,b.使用数据库存数数据:打开数据库,编写数据库语句,执行,关闭数据库.另:写入数据库,字符串可以采用char方式,而从数据库中取出char类型,当char类型有表示中文字符时,会出现乱码,这是因为数据库默认使用ascII编码方式,所以想要正确从数据库中取出中文,需要使用NSString来接受从数据库取出的字符串.</p>
<p>⑤.CoreData:原理是对SQLite的封装,开发者不需要接触sql语句,就可以对数据库进行操作.</p>
<p>#10.ios动态类型和动态绑定</p>
<p>多态:父类指针指向子类对象.</p>
<p>动态类型:只有在运行期,才能确定其真正类型.</p>
<p>动态加载:根据不同的条件,加载不同的资源.32和64位.</p>
<p>#11.深拷贝和浅拷贝的理解.</p>
<p>深拷贝;拷贝的内容.</p>
<p>浅拷贝:拷贝的指针.</p>
<p>深拷贝如:</p>
<p>NSMutableDictionary * dic = [@{} mutableCopy];</p>
<p>NSMutableArray * ary = [@[] mutableCopy];</p>
<p>#12.怎么实现一个singleton的类.</p>
<p>单例是一种设计模式,对象只有一个.缺点:对象不会被释放,如果创建很多的话会占用很多内存,优点:可以当做工具类使用.</p>
<p>static SortDetailsModelDown * single = nil;</p>
<p>+(SortDetailsModelDown *)shareSortDetailsModelDown{</p>
<p>@synchronized(self){</p>
<p>if (!single) {</p>
<p>single = [[SortDetailsModelDown alloc]init];</p>
<p>}</p>
<p>}</p>
<p>return single;</p>
<p>}</p>
<p>#13.什么是安全释放?</p>
<p>先释放再置空.</p>
<p>#14.RunLoop是什么?</p>
<p>事件循环,是线程里面的一个组件.主线程的RunLoop是自动开启的.分为:计时源(timer source),事件源(输入源):input source.防止CPU中断(保证程序执行的线程不会被系统终止).</p>
<p>Runloop提供了一种异步执行代码的机制,并不能并行执行任务,是事件接收和分发机制的一个实现.每一个线程都有其对应的RunLoop,但是默认非主线程的RunLoop是没有运行的,需要为RunLoop添加至少一个事件源,然后run它.</p>
<p>一般情况下我们是没有必要去启动线程的RunLoop的,除非你在一个单独的线程中需要长时间的检测某个事件.</p>
<p>RunLoop,正如其名所示,是线程进入和被线程用来响应事件以及调用事件处理函数的地方.</p>
<p>input source传递异步事件,通常是来自其他线程和不同程序的消息.</p>
<p>timer source传递同步事件.</p>
<p>当有事件发生时,RunLoop会根据具体的事件类型通知应用程序作出响应.</p>
<p>当没有事件发生时,RunLoop会进入休眠状态,从而到达省电的目的.</p>
<p>当事件再次发生时,RunLoop会被重新唤醒,处理事件.</p>
<p>一般在开发中很少会主动创建RunLoop,而通常会把事件添加到RunLoop中.</p>
<p>#15.什么是序列化和反序列化,可以用来做什么?如何在OC中实现复杂对象的存储.</p>
<p>序列化和反序列化:归档和反归档,进行本地化,进行数据存储.</p>
<p>CoreData:数据托管.有四种存储方式:xml,sqlite,二进制,内存.</p>
<p>遵循NSCoding协议之后,进行归档即可实现复杂对象的存储.</p>
<p>#16.写一个标准宏MIN,这个宏输入两个参数并返回较小的一个.</p>
<p>#define MIN(A,B) (A)>(B)?(B):(A)</p>
<p>#17.iPhone OS有没有垃圾回收机制,简易阐述一下OC内存管理.</p>
<p>木有.引用计数,ARC和MRC,swift(自动引用计数).</p>
<p>#18.简述应用程序按HOME键进入后台时的生命周期,以及从后台进入前台时的生命周期.</p>
<p>前者:- (void)applicationWillResignActive:(UIApplication *)application</p>
<ul>
<li>(void)applicationDidEnterBackground:(UIApplication *)application</li>
</ul>
<p>后者:- (void)applicationWillEnterForeground:(UIApplication *)application</p>
<ul>
<li>(void)applicationDidBecomeActive:(UIApplication *)application</li>
</ul>
<p>另:</p>
<p>各个程序运行状态时代理的回调:</p>
<ul>
<li>(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions</li>
</ul>
<p>告诉代理进程启动但还没进入状态保存</p>
<ul>
<li>(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions</li>
</ul>
<p>告诉代理启动基本完成程序准备开始运行</p>
<ul>
<li>(void)applicationWillResignActive:(UIApplication *)application</li>
</ul>
<p>当应用程序将要入非活动状态执行,在此期间,应用程序不接收消息或事件,比如来电话了</p>
<ul>
<li>(void)applicationDidBecomeActive:(UIApplication *)application</li>
</ul>
<p>当应用程序入活动状态执行,这个刚好跟上面那个方法相反</p>
<ul>
<li>(void)applicationDidEnterBackground:(UIApplication *)application</li>
</ul>
<p>当程序被推送到后台的时候调用。所以要设置后台继续运行,则在这个函数里面设置即可</p>
<ul>
<li>(void)applicationWillEnterForeground:(UIApplication *)application</li>
</ul>
<p>当程序从后台将要重新回到前台时候调用,这个刚好跟上面的那个方法相反。</p>
<ul>
<li>(void)applicationWillTerminate:(UIApplication *)application</li>
</ul>