Objective-C面试题全解析:从基础到底层原理
在iOS开发的招聘市场中,Objective-C面试题依然是考察开发者基础功底的重要环节。尽管Swift日益普及,但大量存量代码库和底层框架仍基于OC。本页面旨在提供一份详尽的Objective-C面试题攻略,不仅涵盖语法层面,更深入到Runtime、内存管理及架构设计等核心领域。
对于准备面试的开发者而言,理解“为什么”比知道“是什么”更重要。我们将通过深度解析,帮助你构建完整的知识体系。
一、 Runtime机制深度解析
Runtime是Objective-C的灵魂。在Objective-C面试题中,Runtime相关的题目几乎必考。它允许我们在运行时动态创建类、添加方法、交换方法实现等。
1. 消息发送机制
OC的方法调用本质上是消息发送。编译器会将 [obj method] 转换为 objc_msgSend(obj, @selector(method))。
// 伪代码演示消息发送流程
id objc_msgSend(id self, SEL op, ...) {
Class cls = object_getClass(self);
// 1. 在缓存中查找
// 2. 在类的方法列表中查找
// 3. 在父类中查找
// 4. 消息转发
}
2. 动态方法解析
当调用一个未实现的方法时,Runtime会调用 resolveInstanceMethod:。这是实现属性动态绑定的关键。
示例:动态添加方法
- (BOOL)resolveInstanceMethod:(SEL)sel {
二、 内存管理与ARC原理
内存管理是Objective-C面试题中的另一大重点。理解MRC到ARC的转变,以及底层引用计数的变化,是区分初级与高级开发者的试金石。
1. 引用计数与Retain/Release
在MRC时代,开发者需要手动管理 retain 和 release。ARC通过编译器在编译期插入内存管理调用,但底层逻辑未变。
| 操作 | 引用计数变化 | 适用场景 |
|---|---|---|
| alloc / new / copy / mutableCopy | +1 | 创建新对象 |
| retain | +1 | 增加强引用 |
| release | -1 | 减少强引用 |
| autorelease | 稍后-1 | 延迟释放,用于工厂方法 |
2. 循环引用(Retain Cycle)
循环引用导致内存泄漏。最常见的场景是Block和Delegate。
// 错误示范:循环引用
self.block = ^{
[self doSomething]; // self强引用block,block强引用self
};
// 正确示范:使用weak
__weak typeof(self) weakSelf = self;
self.block = ^{
[weakSelf doSomething];
};
三、 Block底层原理
Block是OC中重要的闭包概念,也是Objective-C面试题中的高频考点。理解Block的结构、捕获变量机制以及内存布局至关重要。
1. Block的内存区域
Block根据存储位置分为三种:
- NSGlobalBlock:没有访问任何自动变量,存放在代码段。
- NSStackBlock:访问了自动变量,存放在栈区。
- NSMallocBlock:栈上的Block被copy后,移动到堆区。
2. 变量捕获机制
Block默认只能读取局部变量,不能修改。若需修改,需使用 __block 修饰符。这涉及到编译器对变量的特殊处理,将其包装为结构体指针。
四、 GCD与多线程编程
并发编程是现代iOS开发的核心。GCD(Grand Central Dispatch)简化了多线程操作。
1. 队列类型
● 串行队列(Serial):一次只执行一个任务,保证顺序。
● 并发队列(Concurrent):可以同时执行多个任务,但执行顺序不确定。
● 主队列(Main Queue):特殊的串行队列,在主线程执行任务。
2. 常见同步方法
dispatch_sync:同步提交任务,会阻塞当前线程。dispatch_async:异步提交任务,不阻塞当前线程。dispatch_barrier_async:栅栏函数,等待前面的任务完成,执行完后,再恢复并发。
五、 架构设计与设计模式
除了语法和底层原理,架构能力也是Objective-C面试题中考察高级职位的关键。
1. MVC与MVVM
MVC(Model-View-Controller)是iOS的基础架构,但Controller往往过于臃肿。MVVM(Model-View-ViewModel)通过ViewModel层剥离了Controller的逻辑,利用KVO实现数据绑定,使代码更易于测试和维护。
2. 常见设计模式
确保一个类只有一个实例,并提供全局访问点。iOS中常用 dispatch_once 实现线程安全的单例。
通过KVO或NotificationCenter实现对象间的通信,解耦发送者和接收者。
利用协议(Protocol)实现回调,是iOS中最常见的通信方式,如UITableViewDelegate。
六、 网友还关心:高频面试问答集锦
基于对大量面试数据的分析,以下是求职者最关心的几个深度问题,我们提供了详细的解答。
Q1: isa指针是什么?
isa指针指向对象所属的类。在64位系统中,isa是一个联合体,包含了类指针、位域(用于ARC、GC、retain count等)等信息。这是实现多态的基础。
Q2: 方法查找缓存(Cache)是如何工作的?
为了提高消息发送效率,Runtime使用了哈希表缓存已查找的方法。当调用方法时,先查缓存,命中则直接调用;未命中则查类方法列表,并将结果存入缓存。
Q1: 如何优化UITableView的性能?
1. 复用Cell(dequeueReusableCellWithIdentifier)。
2. 异步加载图片和数据。
3. 预计算Cell高度,避免布局重绘。
4. 减少Layer层级,避免离屏渲染。
Q2: 什么是离屏渲染?如何避免?
离屏渲染指GPU在当前屏幕缓冲区外开辟新缓冲区进行渲染。常见于圆角、阴影、裁剪等。优化方法:尽量使用贝塞尔曲线绘制圆角,避免过度使用layer.shadowPath。
Q1: URL Loading System与NSURLSession的区别?
NSURLConnection已废弃。NSURLSession提供了更强大的功能,支持后台传输、分块下载、更灵活的配置和代理模式,且生命周期与App绑定更好。
Q2: HTTPS证书绑定(SSL Pinning)是什么?
为了防止中间人攻击,客户端在请求时验证服务器证书是否与预置的证书(或公钥)匹配。这能确保通信双方的身份真实性。
本文档旨在提供 Objective-C面试题 的全面参考。掌握这些知识点,将助你在面试中脱颖而出。
建议结合实际项目经验,深入理解每一处细节。