资深 iOS 开发工程师面试题
一、Objective-C 高级
1. 内存管理
ARC 下如何精确管理对象的生命周期?如何处理复杂引用场景(如 Block 和 Delegate 混合使用)?
答案:- ARC 自动管理引用计数,但需手动处理循环引用。
- 复杂场景:
- Block 捕获 self 和 Delegate 可能导致多重循环引用。
- 使用
__weak typeof(self) weakSelf
在 Block 中避免循环引用。 - Delegate 使用
weak
修饰,防止强引用。
- 示例:
@interface MyViewController : UIViewController
@property (nonatomic, weak) id<Delegate> delegate;
@property (nonatomic, copy) void (^completionBlock)(void);
@end
@implementation MyViewController
- (void)setup {
__weak typeof(self) weakSelf = self;
self.completionBlock = ^{
__strong typeof(weakSelf) strongSelf = weakSelf;
[strongSelf.delegate performAction];
};
}
@end - 高级点:分析
objc_retain
和objc_release
在 ARC 下的插入逻辑,使用 Instruments 的 Allocations 工具跟踪引用计数。
在 MRC 中,手动管理内存的常见问题及优化策略?
答案:- 问题:
- 忘记
release
或autorelease
,导致内存泄漏。 - 过度
retain
,导致对象无法释放。 dealloc
中未正确释放资源。
- 忘记
- 优化:
- 使用命名规范(如
create
方法返回需手动释放对象)。 - 借助
NSAutoreleasePool
管理临时对象。 - 使用静态分析工具检测内存问题。
- 使用命名规范(如
- 注意:MRC 现已淘汰,但理解其原理有助于深入掌握 ARC。
- 问题:
如何在 Objective-C 中实现自定义内存管理策略(类似 ARC 的弱引用表)?
答案:- 使用
objc_setAssociatedObject
和objc_getAssociatedObject
模拟弱引用。 - 示例:
static char kWeakRefKey;
@implementation NSObject (WeakReference)
- (void)setWeakReference:(id)object {
objc_setAssociatedObject(self, &kWeakRefKey, object, OBJC_ASSOCIATION_ASSIGN);
}
- (id)weakReference {
return objc_getAssociatedObject(self, &kWeakRefKey);
}
@end - 高级点:分析 Runtime 的
objc_storeWeak
实现,探讨弱引用表如何管理对象释放。
- 使用
autoreleasepool 的底层实现?如何在高内存压力场景下优化?
答案:- 实现:
NSAutoreleasePool
创建一个池,对象调用autorelease
时加入池,池销毁时释放所有对象。 - 优化:
- 在循环中创建局部
autoreleasepool
减少内存峰值。 - 示例:
@autoreleasepool {
for (int i = 0; i < 1000000; i++) {
NSString *temp = [NSString stringWithFormat:@"%d", i];
// 处理
}
} - 使用
@autoreleasepool
包装高频临时对象创建(如 JSON 解析)。
- 在循环中创建局部
- 高级点:分析
objc_autoreleasePoolPush
和objc_autoreleasePoolPop
的调用栈。
- 实现:
如何调试复杂的内存泄漏问题(如第三方库导致)?
答案:- 使用 Instruments 的 Leaks 和 Allocations 工具。
- 结合
MLeaksFinder
或FBRetainCycleDetector
检测循环引用。 - 手动注入
dealloc
日志,跟踪对象释放。 - 高级点:分析第三方库源码,检查是否正确使用
weak
或unowned
,必要时通过 Category 重写方法。
2. Runtime
Objective-C Runtime 如何支持动态方法解析?实现一个动态添加方法的案例。
答案:- 动态方法解析:
- 使用
resolveInstanceMethod:
或resolveClassMethod:
动态添加方法。 - 示例:
@implementation MyClass
void dynamicMethod(id self, SEL _cmd) {
NSLog(@"Dynamic method called");
}
+ (BOOL)resolveInstanceMethod:(SEL)sel {
if (sel == @selector(dynamicMethod)) {
class_addMethod([self class], sel, (IMP)dynamicMethod, "v@:");
return YES;
}
return [super resolveInstanceMethod:sel];
}
@end
- 使用
- 高级点:探讨
IMP
类型和方法签名编码(如v@:
表示 void 返回、id 和 SEL 参数)。
- 动态方法解析:
消息转发机制的完整流程?如何优化性能?
答案:- 流程:
resolveInstanceMethod:
:尝试动态添加方法。forwardingTargetForSelector:
:转发给其他对象。methodSignatureForSelector:
和forwardInvocation:
:自定义转发逻辑。
- 优化:
- 优先使用
forwardingTargetForSelector:
,避免昂贵的NSInvocation
。 - 缓存方法签名,减少运行时开销。
- 优先使用
- 示例:
@implementation Proxy
- (id)forwardingTargetForSelector:(SEL)aSelector {
return self.target; // 转发给 target 对象
}
@end
- 流程:
如何使用 Runtime 实现 AOP(面向切面编程)?
答案:- 使用
method swizzling
拦截方法,插入切面逻辑。 - 示例(记录方法调用时间):
@implementation UIViewController (AOP)
+ (void)load {
Method original = class_getInstanceMethod(self, @selector(viewDidLoad));
Method swizzled = class_getInstanceMethod(self, @selector(swizzled_viewDidLoad));
method_exchangeImplementations(original, swizzled);
}
- (void)swizzled_viewDidLoad {
CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
[self swizzled_viewDidLoad]; // 调用原方法
NSLog(@"viewDidLoad took %f ms", (CFAbsoluteTimeGetCurrent() - start) * 1000);
}
@end - 坑:多线程下的 swizzling 需加锁;确保方法存在;避免父类/子类冲突。
- 使用
KVO 的实现原理?如何手动实现 KVO?
答案:- 原理:
- KVO 通过 Runtime 动态创建子类(NSKVONotifying_ 前缀),重写 setter 方法,触发通知。
- 手动实现:
- 使用
objc_setAssociatedObject
存储观察者。 - 重写 setter 方法,调用观察者回调。
- 示例:
@implementation MyObject
- (void)setName:(NSString *)name {
[self willChangeValueForKey:@"name"];
objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_RETAIN);
[self didChangeValueForKey:@"name"];
}
@end
- 使用
- 高级点:分析
NSKeyValueObserving
的内部实现,探讨性能瓶颈。
- 原理:
如何使用 Runtime 实现一个简单的依赖注入框架?
答案:- 使用
objc_getAssociatedObject
和objc_setAssociatedObject
动态绑定依赖。 - 示例:
@protocol Service <NSObject>
- (void)perform;
@end
@implementation MyClass
- (void)setService:(id<Service>)service {
objc_setAssociatedObject(self, @selector(service), service, OBJC_ASSOCIATION_RETAIN);
}
- (id<Service>)service {
return objc_getAssociatedObject(self, @selector(service));
}
@end - 高级点:结合 Protocol 和 Runtime 实现类型安全的依赖注入。
- 使用
3. 多线程
如何设计一个高性能的多线程任务调度系统?
答案:- 架构:
- 使用
NSOperationQueue
管理任务,支持优先级和依赖。 - 结合 GCD 的串行/并发队列,优化任务分配。
- 使用
DispatchSemaphore
控制并发上限。
- 使用
- 示例:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 4;
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
// 任务 1
}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
// 任务 2
}];
[op2 addDependency:op1];
[queue addOperations:@[op1, op2] waitUntilFinished:NO]; - 高级点:分析 GCD 的
libdispatch
源码,探讨线程池管理和 QoS 优化。
- 架构:
dispatch_once 的底层实现?如何替代?
答案:- 实现:
dispatch_once
使用原子操作(atomic_compare_exchange
)确保单次执行。 - 替代:
- 使用
static
变量和std::once_flag
(C++)。 - 示例:
static id instance;
static std::once_flag flag;
std::call_once(flag, ^{
instance = [[MyClass alloc] init];
});
- 使用
- 高级点:探讨
dispatch_once_t
的内存结构和性能优化。
- 实现:
如何在高并发场景下避免死锁?
answers:- 避免嵌套锁,使用
dispatch_async
替代同步调用。 - 使用
NSLock
或dispatch_semaphore
控制资源访问。 - 示例:
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
dispatch_async(queue, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
// 访问共享资源
dispatch_semaphore_signal(semaphore);
}); - 高级点:分析死锁的调试方法(如 Thread Sanitizer)。
- 避免嵌套锁,使用
NSOperationQueue 如何实现优先级调度?
答案:- 设置
NSOperation
的queuePriority
或qualityOfService
。 - 示例:
NSOperation *op = [NSBlockOperation blockOperationWithBlock:^{
// 任务
}];
op.queuePriority = NSOperationQueuePriorityHigh;
[queue addOperation:op]; - 高级点:探讨
NSOperationQueue
的线程池管理和调度算法。
- 设置
如何在 Objective-C 中实现线程安全的单例?
答案:- 使用
dispatch_once
确保初始化线程安全。 - 示例:
@implementation Singleton
+ (instancetype)shared {
static Singleton *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[Singleton alloc] init];
});
return instance;
}
@end - 高级点:分析多线程下的单例初始化性能瓶颈。
- 使用
二、Swift 高级
1. struct vs class
struct 和 class 在性能优化中的选择?如何结合 Copy-on-Write 优化 struct?
答案:- 选择:
- struct:适合小数据量、值语义场景(如模型),栈分配性能高。
- class:适合复杂对象、需要继承或引用语义(如视图控制器)。
- Copy-on-Write:
- struct 内部使用引用类型(如 Array)时,需实现 COW 避免不必要复制。
- 示例:
final class Ref<T> {
var value: T
init(_ value: T) { self.value = value }
}
struct MyArray {
private var ref: Ref<[Int]>
var values: [Int] {
get { ref.value }
set {
if !isKnownUniquelyReferenced(&ref) {
ref = Ref(newValue)
} else {
ref.value = newValue
}
}
}
}
- 高级点:分析 struct 的值语义对线程安全的影响。
- 选择:
struct 和 class 在并发环境下的行为差异?
answers:- struct:值类型,复制后独立,天然线程安全。
- class:引用类型,需使用
actor
或锁机制(如NSLock
)保护共享状态。 - 示例:
actor SafeCounter {
var value = 0
func increment() { value += 1 }
} - 高级点:探讨 Swift 6 数据竞争检查对 struct 和 class 的影响。
如何在 struct 中实现类似 class 的继承行为?
答案:- 使用 Protocol 和默认实现模拟继承。
- 示例:
protocol Animal {
func makeSound()
}
extension Animal {
func makeSound() { print("Generic sound") }
}
struct Dog: Animal {
func makeSound() { print("Woof") }
} - 高级点:分析 Protocol 扩展与 class 继承的性能差异。
2. Optional
Optional 的高级用法(如 map、flatMap、compactMap)?
答案:- map:转换 Optional 的值。
- flatMap:处理嵌套 Optional。
- compactMap:过滤 nil 并转换。
- 示例:
let optionalString: String? = "123"
let number = optionalString.map { Int($0) } // Optional<Int>?
let flattened = optionalString.flatMap { Int($0) } // Int?
let array = ["1", "a", "2"].compactMap { Int($0) } // [1, 2] - 高级点:探讨 Optional 的 monadic 性质和编译器优化。
如何自定义 Optional 的行为(如自定义解包逻辑)?
答案:- 通过扩展 Optional 添加方法。
- 示例:
extension Optional {
func unwrap(orDefault defaultValue: Wrapped) -> Wrapped {
return self ?? defaultValue
}
}
let value: String? = nil
print(value.unwrap(orDefault: "default")) // 输出 "default" - 高级点:分析 Optional 的内存布局和性能开销。
3. 协议 & 泛型
如何设计一个类型安全的泛型网络层?
答案:- 使用泛型和 Protocol 约束返回值类型。
- 示例:
protocol APIEndpoint {
associatedtype Response: Decodable
var url: URL { get }
}
struct UserEndpoint: APIEndpoint {
typealias Response = User
var url: URL { URL(string: "https://api.example.com/user")! }
}
class NetworkLayer {
func fetch<T: APIEndpoint>(_ endpoint: T) async throws -> T.Response {
let (data, _) = try await URLSession.shared.data(from: endpoint.url)
return try JSONDecoder().decode(T.Response.self, from: data)
}
} - 高级点:探讨泛型约束对编译器类型推断的影响。
associatedtype 和 where 子句的高级用法?
答案:- associatedtype:定义协议中的类型占位符。
- where 子句:约束关联类型或泛型。
- 示例:
protocol Container {
associatedtype Item where Item: Equatable
func add(_ item: Item)
}
struct Stack<T: Equatable>: Container {
typealias Item = T
var items: [T] = []
func add(_ item: T) { items.append(item) }
} - 高级点:分析 PAT(Protocol with Associated Types)的动态分发问题。
如何实现 Protocol 的动态分发?
answers:- 使用
Self
要求或@objc
协议支持动态分发。 - 示例:
@objc protocol DynamicProtocol {
@objc func perform()
}
class MyClass: DynamicProtocol {
@objc func perform() { print("Performed") }
} - 高级点:探讨
objc
协议与 Swift 原生协议的性能差异。
- 使用
4. 闭包
如何优化闭包在高频场景下的性能?
答案:- 减少捕获变量,降低内存开销。
- 使用
@inlinable
或@inline(__always)
优化编译器内联。 - 示例:
@inlinable func execute(_ closure: () -> Void) {
closure()
} - 高级点:分析闭包捕获的内存分配(堆 vs 栈)。
逃逸闭包和非逃逸闭包的性能差异?
answers:- 非逃逸闭包:编译器可内联,栈分配,性能更高。
- 逃逸闭包:需堆分配,增加引用计数开销。
- 高级点:探讨逃逸闭包的逃逸分析(Escape Analysis)。
如何在闭包中实现复杂的状态管理?
答案:- 使用捕获列表和类包装状态。
- 示例:
class State {
var value = 0
}
let state = State()
let closure = { [state] in state.value += 1 } - 高级点:分析闭包状态管理与 actor 的对比。
5. 多线程(Swift)
如何在 Swift 6 中确保数据竞争安全?
answers:- 使用
actor
隔离状态。 - 实现
Sendable
协议,确保数据跨并发上下文安全。 - 示例:
actor DataStore: Sendable {
private var data: [String: Int] = [:]
func set(_ key: String, value: Int) { data[key] = value }
} - 高级点:分析 Swift 6 的并发检查器(Concurrency Checker)。
- 使用
async/await 如何与 Combine 集成?
answers:- 使用
Future
或PassthroughSubject
桥接。 - 示例:
import Combine
func fetchAsync() async throws -> Int {
return 42
}
let publisher = Future<Int, Error> { promise in
Task {
do { promise(.success(try await fetchAsync())) }
catch { promise(.failure(error)) }
}
} - 高级点:探讨 Combine 与 async/await 的性能差异。
- 使用
如何实现一个自定义并发调度器?
answers:- 使用
DispatchQueue
或RunLoop
实现调度。 - 示例:
struct CustomScheduler {
let queue = DispatchQueue(label: "com.custom.scheduler")
func schedule(_ task: @escaping () -> Void) {
queue.async(execute: task)
}
} - 高级点:分析 Swift Concurrency 的
Continuation
机制。
- 使用
6. Codable
如何在 Codable 中处理复杂嵌套 JSON 和动态键?
answers:- 使用
unkeyedContainer
或singleValueContainer
解码动态结构。 - 示例(动态键):
struct DynamicResponse: Decodable {
let data: [String: Any]
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
data = try container.decode([String: Any].self, forKey: .data)
}
private enum CodingKeys: String, CodingKey { case data }
} - 高级点:探讨
JSONSerialization
与Codable
的性能对比。
- 使用
如何在 Codable 中实现多态解码?
answers:- 使用枚举和
Codable
实现多态。 - 示例:
enum Animal: Codable {
case dog(name: String)
case cat(age: Int)
private enum CodingKeys: String, CodingKey { case type, data }
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let type = try container.decode(String.self, forKey: .type)
switch type {
case "dog": self = .dog(name: try container.decode(String.self, forKey: .data))
case "cat": self = .cat(age: try container.decode(Int.self, forKey: .data))
default: throw DecodingError.dataCorruptedError(forKey: .type, in: container, debugDescription: "Invalid type")
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case .dog(let name):
try container.encode("dog", forKey: .type)
try container.encode(name, forKey: .data)
case .cat(let age):
try container.encode("cat", forKey: .type)
try container.encode(age, forKey: .data)
}
}
} - 高级点:分析多态解码的性能开销和替代方案。
- 使用枚举和
7. 内存管理(Swift)
如何在 Swift 中实现自定义引用计数机制?
answers:- 使用
ManagedBuffer
或自定义引用计数类。 - 示例:
final class RefCounted<T> {
private var count = 0
var value: T
init(_ value: T) { self.value = value }
func retain() { count += 1 }
func release() { count -= 1; if count == 0 { /* 释放 */ } }
} - 高级点:对比 ARC 和手动引用计数的内存管理效率。
- 使用
如何在 Swift 中调试复杂循环引用?
answers:- 使用 Instruments 的 Leaks 工具。
- 注入
deinit
日志,跟踪对象生命周期。 - 使用
swift_mangled_name
检查编译器生成的符号。 - 高级点:分析 Swift ARC 的
objc_retain
和objc_release
实现。
8. 响应式编程
Combine 和 RxSwift 的高级集成场景(如与 UIKit/SwiftUI 结合)?
answers:- Combine:
- 使用
@Published
和ObservableObject
驱动 SwiftUI。 - 示例:
class ViewModel: ObservableObject {
var text = ""
}
struct ContentView: View {
var viewModel = ViewModel()
var body: some View {
Text(viewModel.text)
}
}
- 使用
- RxSwift:
- 使用
RxCocoa
绑定 UIKit 控件。 - 示例:
import RxSwift
import RxCocoa
textField.rx.text.orEmpty
.bind(to: label.rx.text)
.disposed(by: disposeBag)
- 使用
- 高级点:分析 Combine 和 RxSwift 在内存管理和性能上的差异。
- Combine:
如何实现一个自定义 Combine Operator?
answers:- 扩展
Publisher
定义自定义操作符。 - 示例:
extension Publisher {
func customMap<T>(_ transform: @escaping (Output) -> T) -> Publishers.Map<Self, T> {
return map(transform)
}
} - 高级点:分析
Publishers
的内部实现(如Inner
类)。
- 扩展
三、iOS 开发高级
1. UI & 动画
如何优化复杂 UITableView 的性能?
answers:- 优化:
- 使用
dequeueReusableCell
复用单元格。 - 异步加载图片(SDWebImage)。
- 缓存行高(
estimatedHeightForRow
)。 - 避免离屏渲染(减少
cornerRadius
、shadow
)。
- 使用
- 高级点:分析
UITableView
的重用机制和CATiledLayer
的应用。
- 优化:
如何实现复杂 SwiftUI 动画(如多阶段动画)?
answers:- 使用
withAnimation
和Animation
组合。 - 示例:
struct ContentView: View {
private var scale = 1.0
var body: some View {
Circle()
.scaleEffect(scale)
.onTapGesture {
withAnimation(.spring()) {
scale = 1.5
} completion: {
withAnimation(.easeOut) { scale = 1.0 }
}
}
}
} - 高级点:探讨 SwiftUI 的
Animatable
协议和自定义动画曲线。
- 使用
如何在 UIKit 中实现自定义转场动画?
answers:- 实现
UIViewControllerAnimatedTransitioning
和UIViewControllerTransitioningDelegate
。 - 示例:
class CustomTransition: NSObject, UIViewControllerAnimatedTransitioning {
func transitionDuration(using context: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.5
}
func animateTransition(using context: UIViewControllerContextTransitioning) {
guard let toView = context.view(forKey: .to) else { return }
context.containerView.addSubview(toView)
toView.alpha = 0
UIView.animate(withDuration: transitionDuration(using: context), animations: {
toView.alpha = 1
}, completion: { _ in
context.completeTransition(true)
})
}
} - 高级点:分析
CAAnimation
的底层实现。
- 实现
2. 网络
如何设计一个支持离线缓存和断点续传的网络层?
answers:- 使用
URLSessionDownloadTask
支持断点续传。 - 使用
FileManager
缓存响应。 - 示例:
class DownloadManager {
func download(with url: URL, resumeData: Data?) async throws -> URL {
let task = resumeData == nil ?
URLSession.shared.downloadTask(with: url) :
URLSession.shared.downloadTask(withResumeData: resumeData!)
return try await task.download()
}
}
extension URLSessionDownloadTask {
func download() async throws -> URL {
return try await withCheckedThrowingContinuation { continuation in
resume()
// 实现 delegate 监听进度和完成
}
}
} - 高级点:分析
URLSession
的URLSessionTask
状态机。
- 使用
如何实现一个支持 HTTP/2 的网络层?
answers:- 使用
URLSession
的http/2
支持(iOS 9+ 默认启用)。 - 配置
URLSessionConfiguration
的httpShouldUsePipelining
。 - 高级点:探讨 HTTP/2 的多路复用和服务器推送。
- 使用
3. 数据库
如何优化 Core Data 在高并发场景下的性能?
answers:- 使用多
NSManagedObjectContext
(主线程和后台线程)。 - 示例:
let container = NSPersistentContainer(name: "Model")
container.loadPersistentStores { _, _ in
let backgroundContext = container.newBackgroundContext()
backgroundContext.perform {
// 后台操作
try? backgroundContext.save()
}
} - 高级点:分析 Core Data 的
NSMergePolicy
和冲突解决。
- 使用多
如何实现一个自定义 ORM 框架?
answers:- 使用 Codable 和 SQLite 实现轻量级 ORM。
- 示例:
protocol Model: Codable {
static var tableName: String { get }
}
class ORM {
func save<T: Model>(_ model: T) throws {
let data = try JSONEncoder().encode(model)
// 保存到 SQLite
}
} - 高级点:探讨 ORM 的性能瓶颈和索引优化。
4. 性能优化
如何使用 Instruments 分析复杂性能问题?
answers:- Leaks:检测内存泄漏。
- Time Profiler:分析 CPU 热点。
- Core Animation:检查离屏渲染。
- 高级点:结合
os_signpost
自定义性能埋点。
如何优化 App 启动时间?
answers:- 延迟非必要初始化。
- 异步加载资源。
- 使用
dyld
分析动态链接时间。 - 高级点:探讨
dyld3
和dyld4
的启动优化。
5. 架构 & 设计模式
如何设计一个模块化的 iOS 架构?
answers:- 使用组件化(如 SPM 或 CocoaPods)。
- 分层架构:UI 层、业务逻辑层、数据层。
- 示例(路由):
protocol Router {
func route(to destination: String, parameters: [String: Any])
}
class AppRouter: Router {
func route(to destination: String, parameters: [String: Any]) {
// 动态加载模块
}
} - 高级点:分析模块化的动态加载和依赖管理。
如何实现一个依赖注入容器?
answers:- 使用 Protocol 和工厂模式。
- 示例:
protocol Service {
func perform()
}
class DIContainer {
private var services: [String: Any] = [:]
func register<T>(_ type: T.Type, factory: @escaping () -> T) {
services["\(T.self)"] = factory
}
func resolve<T>(_ type: T.Type) -> T? {
return (services["\(T.self)"] as? () -> T)?()
}
} - 高级点:探讨 DI 容器的线程安全和生命周期管理。
四、高频 Swift 面试题(扩展)
1. struct vs class
- 如何在 struct 中实现深拷贝?
- 使用
Codable
或手动复制。 - 示例:
struct DeepCopy: Codable {
var data: [Int]
func copy() -> DeepCopy {
try! JSONDecoder().decode(DeepCopy.self, from: JSONEncoder().encode(self))
}
}
- 使用
2. Codable
- 如何处理动态 JSON 结构?
- 使用
AnyCodable
或自定义解码器。
- 使用
- 如何优化 Codable 的性能?
- 缓存
JSONDecoder
实例,减少反射开销。
- 缓存
3. 多线程
- 如何在 async/await 中实现超时机制?
- 使用
withTimeout
或自定义Task
。 - 示例:
func fetchWithTimeout() async throws -> Data {
try await withTaskCancellationHandler {
try await Task.sleep(nanoseconds: 5_000_000_000) // 5s 超时
throw CancellationError()
} operation: {
return try await fetchData()
}
}
- 使用
4. 内存管理
- 如何在 Swift 中实现自定义内存分配器?
- 使用
UnsafeMutablePointer
和UnsafeBufferPointer
。 - 高级点:分析 Swift 的内存分配器(Swift Allocator)。
- 使用
5. 响应式编程
- 如何在 Combine 中实现自定义 Publisher?
- 继承
Publisher
并实现receive(subscriber:)
。 - 示例:
struct CustomPublisher: Publisher {
typealias Output = Int
typealias Failure = Never
func receive<S: Subscriber>(subscriber: S) where S.Input == Output, S.Failure == Failure {
subscriber.receive(42)
subscriber.receive(completion: .finished)
}
}
- 继承
五、综合问题
设计一个支持插件化的 iOS 架构,动态加载模块。
answers:- 使用
NSBundle
或dlopen
动态加载。 - 结合 Protocol 和 DI 实现模块解耦。
- 高级点:分析 App Store 的动态加载限制。
- 使用
如何实现一个支持 A/B 测试的网络层?
answers:- 使用配置中心动态切换 API。
- 示例:
class ABTestingNetwork {
var endpoint: APIEndpoint
init(config: [String: String]) {
endpoint = config["variant"] == "A" ? EndpointA() : EndpointB()
}
} - 高级点:探讨 A/B 测试的数据收集和分析。
如何在 SwiftUI 中实现复杂的状态管理?
answers:- 使用
ObservableObject
和EnvironmentObject
。 - 示例:
class AppState: ObservableObject {
var user: User?
}
struct ContentView: View {
var state: AppState
var body: some View {
Text(state.user?.name ?? "No user")
}
} - 高级点:分析 SwiftUI 的状态更新机制(diffing 算法)。
- 使用
如何分析和优化第三方库(如 Alamofire)的性能?
answers:- 使用 Instruments 分析网络请求和内存使用。
- 检查源码中的锁机制和异步操作。
- 高级点:探讨 Alamofire 的
Session
和Interceptor
实现。
六、总结
- Objective-C:深入 Runtime、内存管理(MRC/ARC)、多线程(GCD/NSOperation)、动态特性(KVO/Method Swizzling)。
- Swift:深入 struct/class、Codable、Optional、多线程(async/await)、内存管理(ARC)、响应式编程(Combine/RxSwift)。
- iOS 开发:高级 UI(SwiftUI/UIKit)、网络(HTTP/2、断点续传)、数据库(Core Data/ORM)、性能优化(Instruments)、架构设计(模块化/DI)。