iOS知识体系-思维导图面试题答案

一、完善版思维导图(覆盖全部知识点)

mindmap
  root(iOS开发知识体系)
    基础语言
      Objective-C / Swift
        基本语法、特性对比
        内存管理(ARC / MRC)
          引用计数原理、自动释放池
        Runtime(运行时)
          isa指针、方法缓存、消息转发
        Runloop(运行循环)
          模式、事件源、定时器
        多线程
          GCD(队列、任务、信号量)
          NSOperation(依赖、取消、优先级)
        动态特性
          KVC / KVO
          Notification / Delegate / Block
    界面开发
      UIKit核心组件
        UIView、UIViewController、UIWindow
        常用控件(UILabel、UIButton、UITableView等)
      Auto Layout / 布局适配
        Masonry、XIB、Storyboard、Size Classes
      响应链(Responder Chain)
        事件传递、hitTest、手势识别
      动画
        UIView动画、Core Animation、关键帧动画、转场动画
    数据存储与网络
      数据持久化
        plist、UserDefaults、SQLite、CoreData、归档
      网络请求
        URLSession、Alamofire、缓存策略
      数据解析
        JSON(Codable、JSONSerialization)、XML(XMLParser)
      网络安全
        HTTPS、证书校验(SSL Pinning)、AES/RSA加密
    架构与设计模式
      架构模式
        MVC、MVVM、MVP、VIPER、Clean Architecture
      设计模式
        创建型(单例、工厂、建造者)
        结构型(代理、适配器、外观)
        行为型(观察者、策略、命令)
      组件化 / 模块化
        路由(URLRouter、Target-Action)
        中间件(CTMediator、BeeHive)
        私有库管理(CocoaPods、SPM)
      设计原则
        SOLID、高内聚低耦合
    性能优化与调试
      启动优化
        pre-main耗时、动态库合并、二进制重排
      卡顿监测
        Runloop监听、FPS监控、耗时堆栈捕获
      内存泄漏检测
        MLeaksFinder、Instruments、循环引用分析
      包体积优化
        资源压缩、代码混淆、LinkMap分析
    工具与工程化
      版本控制
        Git(分支策略、Rebase、Hook)
      依赖管理
        CocoaPods、Carthage、Swift Package Manager
      持续集成/持续部署
        Jenkins、GitHub Actions、GitLab CI
      测试
        单元测试(XCTest)、UI测试、自动化测试
    底层原理
      Runtime源码分析
        objc_msgSend、方法缓存、关联对象
      Runloop原理
        CFRunloop、mach_msg、事件源
      内存管理底层
        Tagged Pointer、散列表、弱引用表
      类的结构
        isa、元类、class_rw_t、class_ro_t
    推荐学习资源
      数据结构与算法
        《大话数据结构》《算法(第4版)》、LeetCode
      网络
        《图解HTTP》《TCP/IP详解 卷1》
      架构与设计模式
        GitHub优秀仓库、设计模式文档
      iOS底层
        《Objective-C高级编程》《Swift进阶》、Apple官方文档

二、面试题及答案(专业答案分层 + 通俗解释)

1. 什么是ARC?它是如何工作的?

【初级掌握】

ARC(Automatic Reference Counting)是编译器的自动引用计数机制,用于管理 Objective-C 对象的内存。它在编译时自动插入 retain / release / autorelease 方法,减少内存泄漏和野指针的风险。

【中级扩展】

ARC 通过跟踪对象的强引用计数来决定何时释放对象。当引用计数降为 0 时,对象被释放。ARC 还引入了弱引用(__weak),当对象被释放时弱引用自动置 nil。此外,ARC 利用自动释放池(@autoreleasepool)管理临时对象的释放时机。

【高级深入】

ARC 实际上是编译器和运行时协作的结果。编译器在合适位置插入内存管理调用,运行时提供以下支持:

  • 弱引用表:维护所有弱引用,对象销毁时将其置 nil。
  • 自动释放池优化:通过 objc_autoreleasePoolPush/pop 实现池的边界管理。
  • 关联对象的内存管理:通过 objc_setAssociatedObject 的 policy 决定引用关系。
  • 对 Toll-Free Bridging 的处理:需手动或通过 __bridge 关键字管理 CF 对象的内存。

【通俗解释】

ARC 就像自动管家,帮你管理对象内存。当对象不再被使用时,管家会自动把它清理掉,你不需要手动写释放代码,避免内存泄漏。弱引用就像“临时通行证”,不会让对象一直活着。


2. 什么是 Runloop?有哪些应用场景?

【初级掌握】

Runloop 是一个事件处理循环,用于管理线程在无事件时休眠、有事件时处理。常见应用:定时器(NSTimer)、界面刷新、PerformSelector、保持线程存活(如 AFNetworking 常驻线程)。

【中级扩展】

Runloop 基于 mach_msg() 实现,通过用户态和内核态切换实现高效休眠。Runloop 有多个模式(Mode),如 NSDefaultRunLoopModeUITrackingRunLoopMode,同一时间只能运行在一个模式下,可通过切换模式隔离事件。Runloop 还会在每个循环中管理自动释放池(_objc_autoreleasePoolPush/pop)。

【高级深入】

Runloop 的底层是 CFRunloop,包含以下组件:

  • Runloop 对象:包含多个 Mode。
  • Mode:包含 Source/Timer/Observer 集合。
  • Source:分为 Source0(非 mach_port 事件)和 Source1(基于 mach_port 的内核事件)。
  • Observer:监听 Runloop 状态(进入、处理事件、休眠等),用于卡顿监控、界面更新等。

可以通过 CFRunloopObserver 监听 Runloop 状态,实现卡顿监控。例如在子线程中开启 Runloop 并添加 Source,可保活线程。

【通俗解释】

Runloop 是线程的“心跳”,没事就睡觉,有事就处理,确保线程不退出并能响应事件。比如你滑动屏幕时,Runloop 会处理触摸事件,更新界面;没操作时,它就让 CPU 休息省电。


3. 什么是 Category?和 Extension 的区别?

【初级掌握】

  • Category:为类添加方法(不能添加实例变量),运行时有效。
  • Extension:在编译期添加属性和方法,必须要有类的源码,常用于私有属性和方法。

【中级扩展】

Category 可以分散类的实现,但同名方法会覆盖(最后编译的生效)。Extension 本质是匿名 Category,但可以添加实例变量(因为编译期确定)。Category 不能直接添加实例变量,但可以通过关联对象(Associated Object)间接实现。

【高级深入】

Category 的底层结构是 category_t,包含:

  • 实例方法列表、类方法列表
  • 协议列表
  • 属性列表

运行时通过 objc_loadCategory 将 Category 的方法合并到类的方法列表中。合并时,Category 的方法会放在原类方法的前面,所以 Category 方法会“覆盖”原类同名方法(但实际不是覆盖,而是查找顺序问题)。关联对象通过全局哈希表维护,与对象生命周期绑定。

【通俗解释】

Category 像给现有类贴便签添加方法,比如给 NSString 添加一个反转字符串的方法。Extension 像类的小秘密,只能自己用,可以添加私有属性和方法,比如在 .m 文件中声明一个私有属性。


4. 什么是 Block?循环引用如何解决?

【初级掌握】

Block 是封装了函数及其上下文的匿名函数。解决循环引用:使用 __weak 修饰外部变量,避免强引用。

【中级扩展】

Block 有三种类型:

  • 全局 Block(_NSConcreteGlobalBlock):不捕获变量,存储在数据段。
  • 栈 Block(_NSConcreteStackBlock):捕获变量,存储在栈上,需要手动拷贝到堆。
  • 堆 Block(_NSConcreteMallocBlock):栈 Block 拷贝到堆,或手动 copy。

循环引用常见于 Block 强引用 self,self 又持有 Block(如属性),需用 __weak + __strong(内部使用)打破。

【高级深入】

Block 底层是结构体,包含:

  • isa 指针(指向类对象)
  • flags、reserved
  • 函数指针
  • 捕获的变量(按值或按引用)
  • __block 变量会包装成结构体,允许在 Block 内修改变量。

MRC 下使用 __block 可避免循环引用(需手动置 nil),ARC 下 __block 会导致强引用,推荐 __weak。在 Block 内部,如果需要在多行代码中使用弱引用,可先转为强引用(__strong)防止在执行过程中被释放。

【通俗解释】

Block 是一段可以随时执行的代码片段,类似 C 的匿名函数,但能捕获外部变量。循环引用就像两个人互相抓住对方不放,谁也松不开手。解决方法是用 __weak 让其中一人松开手(弱引用),这样两人就自由了。


5. Runtime 中消息发送的流程是怎样的?

【初级掌握】

消息发送流程:通过对象的 isa 找到类,在方法缓存、方法列表中查找,向父类递归查找,未找到则进入动态方法解析、消息转发,最后崩溃。

【中级扩展】

具体步骤:

  1. 通过 isa 指针找到类。
  2. 在类的缓存(cache_t)中查找方法(哈希查找)。
  3. 如果缓存未命中,在当前类的方法列表(method_array_t)中查找。
  4. 如果未找到,沿继承链向上查找(父类缓存、方法列表)。
  5. 如果最终未找到,进入动态方法解析:调用 +resolveInstanceMethod+resolveClassMethod,可在此动态添加方法。
  6. 如果解析未实现,进入快速转发:调用 -forwardingTargetForSelector:,返回一个能处理该消息的对象。
  7. 如果快速转发返回 nil,进入完整转发:调用 -methodSignatureForSelector: 获取方法签名,再通过 -forwardInvocation: 将消息转发给其他对象。
  8. 如果以上都未处理,抛出 doesNotRecognizeSelector: 异常。

【高级深入】

消息发送由 objc_msgSend 实现,使用汇编优化(如 arm64 汇编)以提高性能。方法缓存采用开放式哈希表,缓存的 key 是 selector,value 是方法实现(IMP)。动态方法解析时可调用 class_addMethod。转发阶段可用于实现代理、多继承、AOP 等设计。

【通俗解释】

当调用对象方法时,Runtime 像邮递员,先找自己有没有这个方法,没有就沿着继承链向上找,再没有就进入“动态处理”流程,比如问你能不能现加一个方法,或者转发给别的对象处理,最后如果都不行就报错崩溃。


6. 如何优化 UITableView 的滑动流畅性?

【初级掌握】

避免在 cellForRow 中做耗时操作,使用重用机制(dequeueReusableCell),提前计算并缓存 cell 高度。

【中级扩展】

具体优化措施:

  • 异步绘制:将文本渲染、图片解码放到子线程,减少主线程负担。
  • 减少离屏渲染:避免设置圆角、阴影、mask 等触发离屏渲染的操作,可使用贝塞尔曲线绘制圆角或使用带圆角的图片。
  • 减少视图层级:尽量使用 drawRect 绘制复杂内容,减少 subviews 数量。
  • 预加载:在滑动即将到达时提前加载数据。
  • 使用 shouldRasterize:对静态内容开启光栅化,缓存为位图,但需注意内存。
  • 图片优化:使用合适尺寸的图片,异步解码(如 SDWebImage 的解码选项)。

【高级深入】

可以使用 CADisplayLink 监控帧率,检测卡顿。通过 Runloop 监听卡顿时长,记录堆栈。对于高度缓存,可使用 NSCache 或字典,并注意在数据变化时更新缓存。对于复杂 cell,可考虑使用异步绘制框架(如 AsyncDisplayKit/Texture),将绘制逻辑放到后台线程。还可以利用 UITableView 的预加载 API(prefetchDataSource)提前准备数据。

【通俗解释】

让表格滚动像德芙巧克力一样丝滑,不卡顿。方法包括:提前算好 cell 高度(避免滑动时动态计算)、不要在滚动的瞬间做耗时操作(如图片解码)、减少视图层级和特效(如圆角)、把图片解码放到后台等。


7. 什么是组件化?如何实现?

【初级掌握】

组件化是将 App 拆分为多个独立模块,便于复用和维护。实现方式:使用 CocoaPods 私有库、通过路由进行模块间跳转。

【中级扩展】

组件化实现步骤:

  1. 划分模块:基础组件(网络、存储)、功能组件(分享、支付)、业务组件(首页、我的)。
  2. 解耦:模块间不直接依赖,通过中间件通信。
  3. 路由方案
    • URL 路由:通过注册 URL 和对应的模块,利用 openURL 跳转。
    • Target-Action 方案:利用 Runtime 解耦,如 CTMediator。
  4. 私有库管理:使用 CocoaPods 将每个模块打成私有 Pod,通过版本管理。

【高级深入】

组件化的核心是解耦和复用。CTMediator 基于 Target-Action 和 Runtime,通过分类对外提供服务,内部通过 performSelector 调用目标。BeeHive 基于 Spring 思想,使用注解和模块注册,支持模块生命周期管理。还可以采用面向服务架构(SOA),通过接口暴露服务,利用依赖注入容器管理。组件化还需考虑资源共享(如图片、字符串)、持续集成(各模块独立打包)、二进制化(加快编译)等问题。

【通俗解释】

把 App 拆成独立的小部件,每个小部件可以单独开发、测试、复用,就像乐高积木。团队可以分工合作,改一个模块不影响其他模块,而且这些积木还可以用在其他 App 里。


三、初中高工程师回答指南(各层级备考建议)

🔹 初级工程师

  • 目标定位:能独立完成简单业务模块,掌握基础 API 使用,理解核心概念。
  • 复习重点
    • 语言基础:熟练掌握 OC/Swift 基本语法、内存管理基础(ARC)、常用 Foundation 和 UIKit 类。
    • UI 开发:熟悉 Interface Builder、Auto Layout、ViewController 生命周期、常用控件。
    • 数据存储:了解 UserDefaults、plist、简单的 SQLite 操作。
    • 网络基础:会用 URLSession 发起 GET/POST 请求,解析 JSON。
    • 多线程:掌握 GCD 的基本使用(异步、主队列、全局队列)。
    • 常见问题:循环引用、代理与通知的区别、KVC/KVO 基本使用。
  • 面试技巧
    • 回答问题要简洁,能说出核心概念即可。
    • 遇到不会的,可以诚实表示不了解,但尝试从原理上推测。
    • 展示学习热情和动手能力(如做过的小项目、GitHub 仓库)。

🔸 中级工程师

  • 目标定位:能独立负责复杂模块,理解底层原理,具备性能优化和架构设计能力。
  • 复习重点
    • 底层原理:深入理解 Runtime、Runloop、Block、KVO 实现原理。
    • 性能优化:启动优化、卡顿监测、内存泄漏排查、包体积优化。
    • 架构设计:熟悉 MVC、MVVM 等架构模式,了解组件化思想。
    • 多线程进阶:理解 GCD 源码、NSOperation、锁机制、线程安全。
    • 网络进阶:HTTPS 握手、证书校验、缓存策略、断点续传。
    • 设计模式:掌握常见设计模式并能应用到项目中。
  • 面试技巧
    • 回答要有条理,能结合实际项目经验,举例说明。
    • 对原理性问题,要能画图或举例说明,比如 Runloop 如何影响界面刷新。
    • 主动提出优化方案和踩过的坑,展示解决问题的能力。

🔹 高级工程师

  • 目标定位:能主导技术选型、架构重构、团队指导,具备全局视野和深度思考。
  • 复习重点
    • 底层深度:Runtime 源码、dyld 加载过程、内存管理细节(Tagged Pointer、散列表)、Mach-O 文件格式。
    • 架构演进:组件化、模块化、容器化、跨端方案(React Native、Flutter 对比)。
    • 性能极致:监控体系(APM)、自动化工具、崩溃分析(符号化)、启动优化(二进制重排)。
    • 工程化:CI/CD 搭建、代码规范、自动化测试、二进制化、Code Review 流程。
    • 新技术趋势:SwiftUI、Combine、Concurrency、Swift 6 特性、跨端技术选型。
  • 面试技巧
    • 回答要体现深度和广度,能对比不同方案的优劣(如 CTMediator vs BeeHive)。
    • 强调解决问题的思路和结果,用数据说话(如启动时间从 2s 降到 0.8s)。
    • 展示对团队和流程的改进能力,如何推动技术落地和人才培养。

四、英文术语速查表(中英对照,已核对准确性)

中文术语 英文术语
自动引用计数 Automatic Reference Counting (ARC)
手动引用计数 Manual Reference Counting (MRC)
运行时 Runtime
运行循环 Runloop
多线程 Multithreading
大中央调度 Grand Central Dispatch (GCD)
操作队列 NSOperationQueue
键值编码 Key-Value Coding (KVC)
键值观察 Key-Value Observing (KVO)
通知 Notification
代理 Delegate
代码块 Block
视图控制器 View Controller
自动布局 Auto Layout
响应链 Responder Chain
核心动画 Core Animation
数据持久化 Data Persistence
结构化查询语言 SQLite
核心数据 Core Data
网络会话 URLSession
超文本传输协议 HTTP
超文本传输安全协议 HTTPS
架构模式 Architecture Pattern
模型-视图-控制器 Model-View-Controller (MVC)
模型-视图-视图模型 Model-View-ViewModel (MVVM)
模型-视图-展示器 Model-View-Presenter (MVP)
设计模式 Design Pattern
单例 Singleton
工厂模式 Factory Pattern
观察者模式 Observer Pattern
组件化 Componentization
模块化 Modularization
持续集成 Continuous Integration (CI)
持续部署 Continuous Deployment (CD)
单元测试 Unit Test
UI测试 UI Test
内存泄漏 Memory Leak
循环引用 Retain Cycle / Circular Reference
离屏渲染 Offscreen Rendering
启动时间 Launch Time
卡顿 Stutter / Lag
包体积 App Size
依赖管理 Dependency Management
CocoaPods CocoaPods
Swift包管理器 Swift Package Manager (SPM)
版本控制 Version Control
Git Git
方法调配 Method Swizzling
关联对象 Associated Object
自动释放池 Autorelease Pool
二进制重排 Binary Reordering
堆栈跟踪 Stack Trace
符号化 Symbolication

以上内容已经过全面修订,确保符合您的要求。如有任何需要调整或补充的地方,请随时告知。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容