Skip to content

Commit 9a8496c

Browse files
author
chenyilong
committed
Enhance README format
1 parent 8e58b69 commit 9a8496c

File tree

1 file changed

+33
-31
lines changed

1 file changed

+33
-31
lines changed

01《招聘一个靠谱的iOS》面试题参考答案/《招聘一个靠谱的iOS》面试题参考答案(下).md

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
----------
7171

7272

73-
###25. `_objc_msgForward`函数是做什么的,直接调用它将会发生什么?
73+
### 25. `_objc_msgForward`函数是做什么的,直接调用它将会发生什么?
7474

7575
> `_objc_msgForward`是 IMP 类型,用于消息转发的:当向一个对象发送一条消息,但它并没有实现的时候,`_objc_msgForward`会尝试做消息转发。
7676
@@ -336,7 +336,7 @@ typedef void (*voidIMP)(id, SEL, ...)
336336
337337
同时 [ ***RAC(ReactiveCocoa)*** ](https://github.com/ReactiveCocoa/ReactiveCocoa) 源码中也用到了该方法。
338338
339-
###26. runtime如何实现weak变量的自动置nil?
339+
### 26. runtime如何实现weak变量的自动置nil?
340340
341341
342342
> runtime 对注册的类, 会进行布局,对于 weak 对象会放入一个 hash 表中。 用 weak 指向的对象内存地址作为 key,当此对象的引用计数为0的时候会 dealloc,假如 weak 指向的对象内存地址是a,那么就会以a为键, 在这个 weak 表中搜索,找到所有以a为键的 weak 对象,从而设置为 nil。
@@ -424,7 +424,7 @@ objc_storeWeak(&obj1, 0);
424424

425425

426426

427-
###27. 能否向编译后得到的类中增加实例变量?能否向运行时创建的类中添加实例变量?为什么?
427+
### 27. 能否向编译后得到的类中增加实例变量?能否向运行时创建的类中添加实例变量?为什么?
428428

429429
- 不能向编译后得到的类中增加实例变量;
430430
- 能向运行时创建的类中添加实例变量;
@@ -436,7 +436,7 @@ objc_storeWeak(&obj1, 0);
436436
- 运行时创建的类是可以添加实例变量,调用 `class_addIvar` 函数。但是得在调用 `objc_allocateClassPair` 之后,`objc_registerClassPair` 之前,原因同上。
437437

438438

439-
###28. runloop和线程有什么关系?
439+
### 28. runloop和线程有什么关系?
440440

441441
总的说来,Run loop,正如其名,loop表示某种循环,和run放在一起就表示一直在运行着的循环。实际上,run loop和线程是紧密相连的,可以这样说run loop是为了线程而生,没有线程,它就没有存在的必要。Run loops是线程的基础架构部分, Cocoa 和 CoreFundation 都提供了 run loop 对象方便配置和管理线程的 run loop (以下都以 Cocoa 为例)。每个线程,包括程序的主线程( main thread )都有与之相应的 run loop 对象。
442442

@@ -475,7 +475,7 @@ NSRunLoop *runloop = [NSRunLoop currentRunLoop];
475475

476476
参考链接:[《Objective-C之run loop详解》](http://blog.csdn.net/wzzvictory/article/details/9237973)
477477

478-
###29. runloop的mode作用是什么?
478+
### 29. runloop的mode作用是什么?
479479

480480
model 主要是用来指定事件在运行循环中的优先级的,分为:
481481

@@ -490,7 +490,7 @@ model 主要是用来指定事件在运行循环中的优先级的,分为:
490490
1. NSDefaultRunLoopMode(kCFRunLoopDefaultMode)
491491
2. NSRunLoopCommonModes(kCFRunLoopCommonModes)
492492

493-
###30. 以+ scheduledTimerWithTimeInterval...的方式触发的timer,在滑动页面上的列表时,timer会暂定回调,为什么?如何解决?
493+
### 30. 以+ scheduledTimerWithTimeInterval...的方式触发的timer,在滑动页面上的列表时,timer会暂定回调,为什么?如何解决?
494494

495495
RunLoop只能运行在一种mode下,如果要换mode,当前的loop也需要停下重启成新的。利用这个机制,ScrollView滚动过程中NSDefaultRunLoopMode(kCFRunLoopDefaultMode)的mode会切换到UITrackingRunLoopMode来保证ScrollView的流畅滑动:只能在NSDefaultRunLoopMode模式下处理的事件会影响ScrollView的滑动。
496496

@@ -522,7 +522,7 @@ NSTimer *timer = [NSTimer timerWithTimeInterval:1.0
522522
```
523523
524524
525-
###31. 猜想runloop内部是如何实现的?
525+
### 31. 猜想runloop内部是如何实现的?
526526
527527
> 一般来讲,一个线程一次只能执行一个任务,执行完成后线程就会退出。如果我们需要一个机制,让线程能随时处理事件但并不退出,通常的代码逻辑
528528
是这样的:
@@ -562,18 +562,18 @@ NSTimer *timer = [NSTimer timerWithTimeInterval:1.0
562562
1. [《深入理解RunLoop》](http://blog.ibireme.com/2015/05/18/runloop/#base)
563563
2. 摘自博文[***CFRunLoop***](https://github.com/ming1016/study/wiki/CFRunLoop),原作者是[微博@我就叫Sunny怎么了](http://weibo.com/u/1364395395)
564564
565-
###32. objc使用什么机制管理对象内存?
565+
### 32. objc使用什么机制管理对象内存?
566566
567567
通过 retainCount 的机制来决定对象是否需要释放。
568568
每次 runloop 的时候,都会检查对象的 retainCount,如果retainCount 为 0,说明该对象没有地方需要继续使用了,可以释放掉了。
569569
570-
###33. ARC通过什么方式帮助开发者管理内存?
570+
### 33. ARC通过什么方式帮助开发者管理内存?
571571
<p><del>编译时根据代码上下文,插入 retain/release
572572
</del></p>
573573
ARC相对于MRC,不是在编译时添加retain/release/autorelease这么简单。应该是编译期和运行期两部分共同帮助开发者管理内存。
574574
575575
在编译期,ARC用的是更底层的C接口实现的retain/release/autorelease,这样做性能更好,也是为什么不能在ARC环境下手动retain/release/autorelease,同时对同一上下文的同一对象的成对retain/release操作进行优化(即忽略掉不必要的操作);ARC也包含运行期组件,这个地方做的优化比较复杂,但也不能被忽略。【TODO:后续更新会详细描述下】
576-
###34. 不手动指定autoreleasepool的前提下,一个autorealese对象在什么时刻释放?(比如在一个vc的viewDidLoad中创建)
576+
### 34. 不手动指定autoreleasepool的前提下,一个autorealese对象在什么时刻释放?(比如在一个vc的viewDidLoad中创建)
577577
分两种情况:手动干预释放时机、系统自动去释放。
578578
579579
@@ -620,10 +620,10 @@ ARC相对于MRC,不是在编译时添加retain/release/autorelease这么简单
620620
621621
参考链接:[《黑幕背后的Autorelease》](http://blog.sunnyxx.com/2014/10/15/behind-autorelease/)
622622
623-
###35. BAD_ACCESS在什么情况下出现?
623+
### 35. BAD_ACCESS在什么情况下出现?
624624
访问了野指针,比如对一个已经释放的对象执行了release、访问已经释放对象的成员变量或者发消息。
625625
死循环
626-
###36. 苹果是如何实现autoreleasepool的?
626+
### 36. 苹果是如何实现autoreleasepool的?
627627
628628
autoreleasepool 以一个队列数组的形式实现,主要通过下列三个函数完成.
629629
@@ -638,7 +638,7 @@ autoreleasepool 以一个队列数组的形式实现,主要通过下列三个函
638638
639639
![enter image description here](http://i60.tinypic.com/15mfj11.jpg)
640640
641-
###37. 使用block时什么情况会发生引用循环,如何解决?
641+
### 37. 使用block时什么情况会发生引用循环,如何解决?
642642
一个对象中强引用了block,在block中又强引用了该对象,就会发射循环引用。
643643
644644
解决方法是将该对象使用__weak或者__block修饰符修饰之后再在block中使用。
@@ -653,7 +653,7 @@ autoreleasepool 以一个队列数组的形式实现,主要通过下列三个函
653653
654654
检测代码中是否存在循环引用问题,可使用 Facebook 开源的一个检测工具 [***FBRetainCycleDetector***](https://github.com/facebook/FBRetainCycleDetector) 。
655655
656-
###38. 在block内如何修改block外部变量?
656+
### 38. 在block内如何修改block外部变量?
657657
默认情况下,在block中访问的外部变量是复制过去的,即:**写操作不对原变量生效**。但是你可以加上 `__block` 来让其写操作生效,示例代码如下:
658658
659659
@@ -740,7 +740,7 @@ autoreleasepool 以一个队列数组的形式实现,主要通过下列三个函
740740
741741
上文已经说过:**Block不允许修改外部变量的值**,这里所说的外部变量的值,指的是栈中指针的内存地址。栈区是红灯区,堆区才是绿灯区。
742742
743-
###39. 使用系统的某些block api(如UIView的block版本写动画时),是否也考虑引用循环问题?
743+
### 39. 使用系统的某些block api(如UIView的block版本写动画时),是否也考虑引用循环问题?
744744
745745
系统的某些block api中,UIView的block版本写动画时不需要考虑,但也有一些api 需要考虑:
746746
@@ -797,13 +797,13 @@ __typeof__(self) strongSelf = weakSelf;
797797
self --> _observer --> block --> self 显然这也是一个循环引用。
798798

799799
检测代码中是否存在循环引用问题,可使用 Facebook 开源的一个检测工具 [***FBRetainCycleDetector***](https://github.com/facebook/FBRetainCycleDetector)
800-
###40. GCD的队列(`dispatch_queue_t`)分哪两种类型?
800+
### 40. GCD的队列(`dispatch_queue_t`)分哪两种类型?
801801

802802

803803
1. 串行队列Serial Dispatch Queue
804804
2. 并行队列Concurrent Dispatch Queue
805805

806-
###41. 如何用GCD同步若干个异步调用?(如根据若干个url异步加载多张图片,然后在都下载完成后合成一张整图)
806+
### 41. 如何用GCD同步若干个异步调用?(如根据若干个url异步加载多张图片,然后在都下载完成后合成一张整图)
807807

808808
使用Dispatch Group追加block到Global Group Queue,这些block如果全部执行完毕,就会执行Main Dispatch Queue中的结束处理的block。
809809

@@ -817,7 +817,7 @@ dispatch_group_notify(group, dispatch_get_main_queue(), ^{
817817
// 合并图片
818818
});
819819
```
820-
###42. `dispatch_barrier_async`的作用是什么?
820+
### 42. `dispatch_barrier_async`的作用是什么?
821821
在并行队列中,为了保持某些任务的顺序,需要等待一些任务完成后才能继续进行,使用 barrier 来等待之前任务完成,避免数据竞争等问题。
822822
`dispatch_barrier_async` 函数会等待追加到Concurrent Dispatch Queue并行队列中的操作全部执行完之后,然后再执行 `dispatch_barrier_async` 函数追加的处理,等 `dispatch_barrier_async` 追加的处理执行结束之后,Concurrent Dispatch Queue才恢复之前的动作继续执行。
823823
@@ -826,12 +826,12 @@ dispatch_group_notify(group, dispatch_get_main_queue(), ^{
826826
(注意:使用 `dispatch_barrier_async` ,该函数只能搭配自定义并行队列 `dispatch_queue_t` 使用。不能使用: `dispatch_get_global_queue` ,否则 `dispatch_barrier_async` 的作用会和 `dispatch_async` 的作用一模一样。 )
827827
828828
829-
###43. 苹果为什么要废弃`dispatch_get_current_queue`?
829+
### 43. 苹果为什么要废弃`dispatch_get_current_queue`?
830830
831831
`dispatch_get_current_queue`容易造成死锁
832832
833833
834-
###44. 以下代码运行结果如何?
834+
### 44. 以下代码运行结果如何?
835835
836836
837837
- (void)viewDidLoad
@@ -847,7 +847,7 @@ dispatch_group_notify(group, dispatch_get_main_queue(), ^{
847847
只输出:1 。发生主线程锁死。
848848
849849
850-
###45. addObserver:forKeyPath:options:context:各个参数的作用分别是什么,observer中需要实现哪个方法才能获得KVO回调?
850+
### 45. addObserver:forKeyPath:options:context:各个参数的作用分别是什么,observer中需要实现哪个方法才能获得KVO回调?
851851
852852
```Objective-C
853853
// 添加键值观察
@@ -874,7 +874,7 @@ observer中需要实现一下方法:
874874
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
875875
```
876876

877-
###46. 如何手动触发一个value的KVO
877+
### 46. 如何手动触发一个value的KVO
878878

879879
所谓的“手动触发”是区别于“自动触发”:
880880

@@ -934,25 +934,25 @@ observer中需要实现一下方法:
934934

935935
参考链接: [Manual Change Notification---Apple 官方文档](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/KeyValueObserving/Articles/KVOCompliance.html#//apple_ref/doc/uid/20002178-SW3)
936936

937-
###47. 若一个类有实例变量 `NSString *_foo` ,调用setValue:forKey:时,可以以foo还是 `_foo` 作为key?
937+
### 47. 若一个类有实例变量 `NSString *_foo` ,调用setValue:forKey:时,可以以foo还是 `_foo` 作为key?
938938
都可以。
939-
###48. KVC的keyPath中的集合运算符如何使用?
939+
### 48. KVC的keyPath中的集合运算符如何使用?
940940

941941
1. 必须用在集合对象上或普通对象的集合属性上
942942
2. 简单集合运算符有@avg@count@max@min@sum
943943
3. 格式 @"@sum.age"或 @"集合属性[email protected]"
944944

945-
###49. KVC和KVO的keyPath一定是属性么?
945+
### 49. KVC和KVO的keyPath一定是属性么?
946946
KVC 支持实例变量,KVO 只能手动支持[手动设定实例变量的KVO实现监听](https://yq.aliyun.com/articles/30483)
947-
###50. 如何关闭默认的KVO的默认实现,并进入自定义的KVO实现?
947+
### 50. 如何关闭默认的KVO的默认实现,并进入自定义的KVO实现?
948948

949949

950950
请参考:
951951

952952
1. [《如何自己动手实现 KVO》](http://tech.glowing.com/cn/implement-kvo/)
953953
2. [**KVO for manually implemented properties**]( http://stackoverflow.com/a/10042641/3395008 )
954954

955-
###51. apple用什么方式实现对一个对象的KVO?
955+
### 51. apple用什么方式实现对一个对象的KVO?
956956

957957

958958

@@ -1049,7 +1049,7 @@ KVO 在实现中通过 ` isa 混写(isa-swizzling)` 把这个对象的 isa
10491049

10501050
而“回调的调用时机”就是在你调用 `didChangeValueForKey:` 方法时。
10511051

1052-
###52. IBOutlet连出来的视图属性为什么可以被设置成weak?
1052+
### 52. IBOutlet连出来的视图属性为什么可以被设置成weak?
10531053

10541054
参考链接:[ ***Should IBOutlets be strong or weak under ARC?*** ](http://stackoverflow.com/questions/7678469/should-iboutlets-be-strong-or-weak-under-arc)
10551055

@@ -1060,12 +1060,12 @@ KVO 在实现中通过 ` isa 混写(isa-swizzling)` 把这个对象的 isa
10601060

10611061
不过这个回答漏了个重要知识,使用storyboard(xib不行)创建的vc,会有一个叫_topLevelObjectsToKeepAliveFromStoryboard的私有数组强引用所有top level的对象,所以这时即便outlet声明成weak也没关系
10621062

1063-
###53. IB中User Defined Runtime Attributes如何使用?
1063+
### 53. IB中User Defined Runtime Attributes如何使用?
10641064

10651065
它能够通过KVC的方式配置一些你在interface builder 中不能配置的属性。当你希望在IB中作尽可能多得事情,这个特性能够帮助你编写更加轻量级的viewcontroller
10661066

10671067

1068-
###54. 如何调试BAD_ACCESS错误
1068+
### 54. 如何调试BAD_ACCESS错误
10691069

10701070

10711071
1. 重写object的respondsToSelector方法,现实出现EXEC_BAD_ACCESS前访问的最后一个object
@@ -1077,7 +1077,7 @@ KVO 在实现中通过 ` isa 混写(isa-swizzling)` 把这个对象的 isa
10771077
用法如下:在配置中勾选✅Enable Address Sanitizer
10781078
![enter image description here](https://developer.apple.com/library/prerelease/ios/documentation/DeveloperTools/Conceptual/WhatsNewXcode/Art/xc7-asan_2x.png)
10791079

1080-
###55. lldb(gdb)常用的调试命令?
1080+
### 55. lldb(gdb)常用的调试命令?
10811081

10821082
- breakpoint 设置断点定位到某一个函数
10831083
- n 断点指针下一步
@@ -1095,3 +1095,5 @@ KVO 在实现中通过 ` isa 混写(isa-swizzling)` 把这个对象的 isa
10951095

10961096
Posted by [微博@iOS程序犭袁](http://weibo.com/luohanchenyilong/)
10971097
原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | [Creative Commons BY-NC-ND 3.0](http://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh)
1098+
1099+

0 commit comments

Comments
 (0)