Skip to content

Commit 855e7d8

Browse files
Update 《招聘一个靠谱的iOS》面试题参考答案(上).md
1 parent a183129 commit 855e7d8

File tree

1 file changed

+29
-29
lines changed

1 file changed

+29
-29
lines changed

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

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
----------
1212

13-
#索引
13+
# 索引
1414

1515
1. [风格纠错题](https://github.com/ChenYilong/iOSInterviewQuestions/blob/master/01《招聘一个靠谱的iOS》面试题参考答案/《招聘一个靠谱的iOS》面试题参考答案(上).md#1-风格纠错题)
1616

@@ -56,7 +56,7 @@
5656
5757
22. 22--55题,请看下篇。
5858
59-
###1. 风格纠错题
59+
### 1. 风格纠错题
6060
![enter image description here](http://i.imgur.com/O7Zev94.png)
6161
修改完的代码:
6262
@@ -93,7 +93,7 @@ typedef NS_ENUM(NSInteger, CYLSex) {
9393
。因为***硬伤部分***没什么技术含量,为了节省大家时间,放在后面讲,大神请直接看***优化部分***
9494

9595

96-
####***优化部分***
96+
#### ***优化部分***
9797

9898
4. enum 建议使用 `NS_ENUM``NS_OPTIONS` 宏来定义枚举类型,参见官方的 [Adopting Modern Objective-C](https://developer.apple.com/library/ios/releasenotes/ObjectiveC/ModernizationObjC/AdoptingModernObjective-C/AdoptingModernObjective-C.html) 一文:
9999

@@ -245,7 +245,7 @@ typedef NS_ENUM(NSInteger, CYLSex) {
245245
```
246246
属性的参数应该按照下面的顺序排列: 原子性,读写 和 内存管理。 这样做你的属性更容易修改正确,并且更好阅读。这在[《禅与Objective-C编程艺术 >》](https://github.com/oa414/objc-zen-book-cn#属性定义)里有介绍。而且习惯上修改某个属性的修饰符时,一般从属性名从右向左搜索需要修动的修饰符。最可能从最右边开始修改这些属性的修饰符,根据经验这些修饰符被修改的可能性从高到底应为:内存管理 > 读写权限 >原子操作。
247247

248-
####***硬伤部分***
248+
#### ***硬伤部分***
249249

250250
1. 在-和(void)之间应该有一个空格
251251
3. enum 中驼峰命名法和下划线命名法混用错误:枚举类型的命名规则和函数的命名规则相同:命名时使用驼峰命名法,勿使用下划线命名法。
@@ -263,7 +263,7 @@ typedef NS_ENUM(NSInteger, CYLSex) {
263263
7. <p><del>doLogIn方法中的 `LogIn` 命名不清晰:笔者猜测是login的意思,应该是粗心手误造成的。
264264
(勘误: `Login` 是名词, `LogIn` 是动词,都表示登陆的意思。见: [ ***Log in vs. login*** ](http://grammarist.com/spelling/log-in-login/))</del></p>
265265

266-
###2. 什么情况使用 weak 关键字,相比 assign 有什么不同?
266+
### 2. 什么情况使用 weak 关键字,相比 assign 有什么不同?
267267
什么情况使用 weak 关键字?
268268

269269

@@ -280,7 +280,7 @@ NSlnteger 等)的简单赋值操作。
280280

281281
2. assign 可以用非 OC 对象,而 weak 必须用于 OC 对象
282282

283-
###3. 怎么用 copy 关键字?
283+
### 3. 怎么用 copy 关键字?
284284
用途:
285285

286286
1. NSString、NSArray、NSDictionary 等等经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary;
@@ -314,7 +314,7 @@ NSlnteger 等)的简单赋值操作。
314314
该问题在下文中也有论述:***@property声明的NSString(或NSArray,NSDictionary)经常使用copy关键字,为什么?如果改用strong关键字,可能造成什么问题?***
315315

316316

317-
###4. 这个写法会出什么问题: `@property (copy) NSMutableArray *array;`
317+
### 4. 这个写法会出什么问题: `@property (copy) NSMutableArray *array;`
318318
两个问题:1、添加,删除,修改数组内的元素的时候,程序会因为找不到对应的方法而崩溃.因为 copy 就是复制一个不可变 NSArray 的对象;2、使用了 atomic 属性会严重影响性能 ;
319319

320320
第1条的相关原因在下文中有论述***《用@property声明的NSString(或NSArray,NSDictionary)经常使用 copy 关键字,为什么?如果改用strong关键字,可能造成什么问题?》*** 以及上文***《怎么用 copy 关键字?》***也有论述。
@@ -366,7 +366,7 @@ self.mutableArray = array;
366366
因此,开发iOS程序时一般都会使用 nonatomic 属性。但是在开发 Mac OS X 程序时,使用
367367
atomic 属性通常都不会有性能瓶颈。
368368

369-
###5. 如何让自己的类用 copy 修饰符?如何重写带 copy 关键字的 setter?
369+
### 5. 如何让自己的类用 copy 修饰符?如何重写带 copy 关键字的 setter?
370370

371371

372372
> 若想令自己所写的对象具有拷贝功能,则需实现 NSCopying 协议。如果自定义的对象分为可变版本与不可变版本,那么就要同时实现 `NSCopying``NSMutableCopying` 协议。
@@ -642,7 +642,7 @@ typedef NS_ENUM(NSInteger, CYLSex) {
642642
643643
644644
645-
###6. @property 的本质是什么?ivar、getter、setter 是如何生成并添加到这个类中的
645+
### 6. @property 的本质是什么?ivar、getter、setter 是如何生成并添加到这个类中的
646646
647647
**@property 的本质是什么?**
648648
@@ -750,15 +750,15 @@ typedef struct {
750750

751751
也就是说我们每次在增加一个属性,系统都会在 `ivar_list` 中添加一个成员变量的描述,在 `method_list` 中增加 setter 与 getter 方法的描述,在属性列表中增加一个属性的描述,然后计算该属性在对象中的偏移量,然后给出 setter 与 getter 方法对应的实现,在 setter 方法中从偏移量的位置开始赋值,在 getter 方法中从偏移量开始取值,为了能够读取正确字节数,系统对象偏移量的指针类型进行了类型强转.
752752

753-
###7. @protocol 和 category 中如何使用 @property
753+
### 7. @protocol 和 category 中如何使用 @property
754754

755755
1. 在 protocol 中使用 property 只会生成 setter 和 getter 方法声明,我们使用属性的目的,是希望遵守我协议的对象能实现该属性
756756
2. category 使用 @property 也是只会生成 setter 和 getter 方法的声明,如果我们真的需要给 category 增加属性的实现,需要借助于运行时的两个函数:
757757

758758
1. `objc_setAssociatedObject`
759759
2. `objc_getAssociatedObject`
760760

761-
###8. runtime 如何实现 weak 属性
761+
### 8. runtime 如何实现 weak 属性
762762

763763
要实现 weak 属性,首先要搞清楚 weak 属性的特点:
764764

@@ -1058,7 +1058,7 @@ NSObject *foo = [[NSObject alloc] init];
10581058
参考博文: [***Fun With the Objective-C Runtime: Run Code at Deallocation of Any Object***](http://stackoverflow.com/a/31560217/3395008)
10591059
10601060
1061-
###9. @property中有哪些属性关键字?/ @property 后面可以有哪些修饰符?
1061+
### 9. @property中有哪些属性关键字?/ @property 后面可以有哪些修饰符?
10621062
属性可以拥有的特质分为四类:
10631063
10641064
1. 原子性--- `nonatomic` 特质
@@ -1149,7 +1149,7 @@ void objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id newValue, BOOL ato
11491149
}
11501150
```
11511151

1152-
###10. weak属性需要在dealloc中置nil么?
1152+
### 10. weak属性需要在dealloc中置nil么?
11531153
不需要。
11541154

11551155

@@ -1184,13 +1184,13 @@ void objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id newValue, BOOL ato
11841184

11851185

11861186

1187-
###11. @synthesize@dynamic分别有什么作用?
1187+
### 11. @synthesize@dynamic分别有什么作用?
11881188

11891189
1. @property有两个对应的词,一个是 @synthesize,一个是 @dynamic。如果 @synthesize@dynamic都没写,那么默认的就是`@syntheszie var = _var;`
11901190
2. @synthesize 的语义是如果你没有手动实现 setter 方法和 getter 方法,那么编译器会自动为你加上这两个方法。
11911191
3. @dynamic 告诉编译器:属性的 setter 与 getter 方法由用户自己实现,不自动生成。(当然对于 readonly 的属性只需提供 getter 即可)。假如一个属性被声明为 @dynamic var,然后你没有提供 @setter方法和 @getter 方法,编译的时候没问题,但是当程序运行到 `instance.var = someVar`,由于缺 setter 方法会导致程序崩溃;或者当运行到 `someVar = var` 时,由于缺 getter 方法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定。
11921192

1193-
###12. ARC下,不显式指定任何属性关键字时,默认的关键字都有哪些?
1193+
### 12. ARC下,不显式指定任何属性关键字时,默认的关键字都有哪些?
11941194

11951195
1. 对应基本数据类型默认关键字是
11961196

@@ -1205,7 +1205,7 @@ void objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id newValue, BOOL ato
12051205

12061206
2. [ ***Variable property attributes or Modifiers in iOS*** ](http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html)
12071207

1208-
###13. 用@property声明的NSString(或NSArray,NSDictionary)经常使用copy关键字,为什么?如果改用strong关键字,可能造成什么问题?
1208+
### 13. 用@property声明的NSString(或NSArray,NSDictionary)经常使用copy关键字,为什么?如果改用strong关键字,可能造成什么问题?
12091209

12101210

12111211
1. 因为父类指针可以指向子类对象,使用 copy 的目的是为了让本对象的属性不受外界影响,使用 copy 无论给我传入是一个可变对象还是不可对象,我本身持有的就是一个不可变的副本.
@@ -1260,7 +1260,7 @@ void objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id newValue, BOOL ato
12601260
1. 对非集合类对象的 copy 与 mutableCopy 操作;
12611261
2. 对集合类对象的 copy 与 mutableCopy 操作。
12621262

1263-
####1. 对非集合类对象的copy操作:
1263+
#### 1. 对非集合类对象的copy操作:
12641264

12651265
在非集合类对象中:对 immutable 对象进行 copy 操作,是指针复制,mutableCopy 操作时内容复制;对 mutable 对象进行 copy 和 mutableCopy 都是内容复制。用代码简单表示如下:
12661266

@@ -1291,7 +1291,7 @@ stringCopy 的值也不会因此改变,但是如果不使用 copy,stringCopy
12911291

12921292
> @property 声明 NSString、NSArray、NSDictionary 经常使用 copy 关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,他们之间可能进行赋值操作,为确保对象中的字符串值不会无意间变动,应该在设置新属性值时拷贝一份。
12931293
1294-
####2、集合类对象的copy与mutableCopy
1294+
#### 2、集合类对象的copy与mutableCopy
12951295

12961296
集合类对象是指 NSArray、NSDictionary、NSSet ... 之类的对象。下面先看集合类immutable对象使用 copy 和 mutableCopy 的一个例子:
12971297

@@ -1328,7 +1328,7 @@ NSMutableArray *mCopyArray = [array mutableCopy];
13281328

13291329
参考链接:[iOS 集合的深复制与浅复制](https://www.zybuluo.com/MicroCai/note/50592)
13301330

1331-
###14. @synthesize合成实例变量的规则是什么?假如property名为foo,存在一个名为`_foo`的实例变量,那么还会自动合成新变量么?
1331+
### 14. @synthesize合成实例变量的规则是什么?假如property名为foo,存在一个名为`_foo`的实例变量,那么还会自动合成新变量么?
13321332
在回答之前先说明下一个概念:
13331333

13341334
> 实例变量 = 成员变量 = ivar
@@ -1385,7 +1385,7 @@ NSMutableArray *mCopyArray = [array mutableCopy];
13851385
![enter image description here](http://i.imgur.com/t28ge4W.png)
13861386

13871387

1388-
###15. 在有了自动合成属性实例变量之后,@synthesize还有哪些使用场景?
1388+
### 15. 在有了自动合成属性实例变量之后,@synthesize还有哪些使用场景?
13891389

13901390
回答这个问题前,我们要搞清楚一个问题,什么情况下不会autosynthesis(自动合成)?
13911391

@@ -1471,7 +1471,7 @@ NSMutableArray *mCopyArray = [array mutableCopy];
14711471
2. 要么如第17行:使用`@synthesize foo = _foo;` ,关联 @property 与 ivar。
14721472
14731473
更多信息,请戳- 》[ ***When should I use @synthesize explicitly?*** ](http://stackoverflow.com/a/19821816/3395008)
1474-
###16. objc中向一个nil对象发送消息将会发生什么?
1474+
### 16. objc中向一个nil对象发送消息将会发生什么?
14751475
在 Objective-C 中向 nil 发送消息是完全有效的——只是在运行时不会有任何作用:
14761476
14771477
1. 如果一个方法返回值是一个对象,那么发送给nil的消息将返回0(nil)。例如:
@@ -1522,7 +1522,7 @@ objc在向一个对象发送消息时,runtime库会根据对象的isa指针找
15221522
那么,回到本题,如果向一个nil对象发送消息,首先在寻找对象的isa指针时就是0地址返回了,所以不会出现任何错误。
15231523
15241524
1525-
###17. objc中向一个对象发送消息[obj foo]和`objc_msgSend()`函数之间有什么关系?
1525+
### 17. objc中向一个对象发送消息[obj foo]和`objc_msgSend()`函数之间有什么关系?
15261526
具体原因同上题:该方法编译之后就是`objc_msgSend()`函数调用.
15271527
15281528
我们用 clang 分析下,clang 提供一个命令,可以将Objective-C的源码改写成C++语言,借此可以研究下[obj foo]和`objc_msgSend()`函数之间有什么关系。
@@ -1569,7 +1569,7 @@ clang -rewrite-objc main.m
15691569

15701570
> [obj foo];在objc动态编译时,会被转意为:`objc_msgSend(obj, @selector(foo));`
15711571
1572-
###18. 什么时候会报unrecognized selector的异常?
1572+
### 18. 什么时候会报unrecognized selector的异常?
15731573

15741574
简单来说:
15751575

@@ -1603,7 +1603,7 @@ objc在向一个对象发送消息时,runtime库会根据对象的isa指针找
16031603

16041604
为了能更清晰地理解这些方法的作用,git仓库里也给出了一个Demo,名称叫“ `_objc_msgForward_demo` ”,可运行起来看看。
16051605

1606-
###19. 一个objc对象如何进行内存布局?(考虑有父类的情况)
1606+
### 19. 一个objc对象如何进行内存布局?(考虑有父类的情况)
16071607

16081608
- 所有父类的成员变量和自己的成员变量都会存放在该对象所对应的存储空间中.
16091609
- 每一个对象内部都有一个isa指针,指向他的类对象,类对象中存放着本对象的
@@ -1640,11 +1640,11 @@ objc在向一个对象发送消息时,runtime库会根据对象的isa指针找
16401640
如图:
16411641
![enter image description here](http://i.imgur.com/w6tzFxz.png)
16421642

1643-
###20. 一个objc对象的isa的指针指向什么?有什么作用?
1643+
### 20. 一个objc对象的isa的指针指向什么?有什么作用?
16441644

16451645
指向他的类对象,从而可以找到对象上的方法
16461646

1647-
###21. 下面的代码输出什么?
1647+
### 21. 下面的代码输出什么?
16481648

16491649

16501650

@@ -1851,11 +1851,11 @@ objc Runtime开源代码对- (Class)class方法的实现:
18511851
参考链接:[微博@Chun_iOS](http://weibo.com/junbbcom)的博文[刨根问底Objective-C Runtime(1)- Self & Super](http://chun.tips/blog/2014/11/05/bao-gen-wen-di-objective%5Bnil%5Dc-runtime(1)%5Bnil%5D-self-and-super/)
18521852

18531853

1854-
###22. runtime如何通过selector找到对应的IMP地址?(分别考虑类方法和实例方法)
1854+
### 22. runtime如何通过selector找到对应的IMP地址?(分别考虑类方法和实例方法)
18551855

18561856
每一个类对象中都一个方法列表,方法列表中记录着方法的名称,方法实现,以及参数类型,其实selector本质就是方法名称,通过这个方法名称就可以在方法列表中找到对应的方法实现.
18571857

1858-
###23. 使用runtime Associate方法关联的对象,需要在主对象dealloc的时候释放么?
1858+
### 23. 使用runtime Associate方法关联的对象,需要在主对象dealloc的时候释放么?
18591859

18601860
- 在ARC下不需要。
18611861
- <p><del> 在MRC中,对于使用retain或copy策略的需要 。</del></p>在MRC下也不需要
@@ -1936,7 +1936,7 @@ objc_setAssociatedObject (
19361936
19371937
19381938
1939-
###24. objc中的类方法和实例方法有什么本质区别和联系?
1939+
### 24. objc中的类方法和实例方法有什么本质区别和联系?
19401940
19411941
类方法:
19421942

0 commit comments

Comments
 (0)