常见的iOS性能优化点,比如内存管理、UI优化、多线程处理、网络请求优化、启动优化、I/O操作、图像处理、算法优化、工具使用等。
一、内存优化
1. 循环引用处理
-
原理:对象之间的强引用导致无法释放,内存泄漏。
-
Objective-C:
-
使用
__weak
或__unsafe_unretained
(需谨慎)打破循环:ini__weak typeof(self) weakSelf = self; self.block = ^{ // 弱引用避免循环 [weakSelf doSomething]; };
-
对
NSTimer
使用NSProxy
或weak
委托模式。
-
-
Swift:
-
使用
[weak self]
或[unowned self]
捕获列表:swiftself.block = { [weak self] in guard let self = self else { return } self.doSomething() }
-
unowned
适用于生命周期相同或更短的场景(如父子关系)。
-
2. 自动释放池(Autorelease Pool)
-
原理:批量创建临时对象时,及时释放内存。
-
Objective-C:
ini@autoreleasepool { for (int i = 0; i < 100000; i++) { NSString *temp = [NSString stringWithFormat:@"%d", i]; // 临时对象会被及时释放 } }
-
Swift:
rustautoreleasepool { for i in 0..<100000 { let temp = "(i)" // 临时对象在块结束时释放 } }
-
适用场景:大量临时对象生成(如解析 JSON 数组、图像处理)。
二、UI 性能优化
1. 避免离屏渲染(Offscreen Rendering)
-
原理:离屏渲染(如圆角、阴影)触发 GPU 额外绘制,导致卡顿。
-
优化方法:
-
预渲染圆角:
-
Objective-C:
ini// 使用 Core Graphics 提前绘制圆角 UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0); [[UIBezierPath bezierPathWithRoundedRect:view.bounds cornerRadius:10] addClip]; [image drawInRect:view.bounds]; UIImage *roundedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); view.layer.contents = (id)roundedImage.CGImage;
-
Swift:
inilet renderer = UIGraphicsImageRenderer(size: view.bounds.size) let roundedImage = renderer.image { context in UIBezierPath(roundedRect: view.bounds, cornerRadius: 10).addClip() image.draw(in: view.bounds) } view.layer.contents = roundedImage.cgImage
-
-
避免
shouldRasterize
:除非复用图层,否则会触发离屏渲染。
-
2. Cell 复用与轻量化
-
原理:避免频繁创建/销毁 Cell,减少 CPU 和内存压力。
-
Objective-C:
ini- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // 复用 Cell UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellID"]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CellID"]; } // 轻量配置(避免复杂计算) cell.textLabel.text = [self.dataArray[indexPath.row] title]; return cell; }
-
Swift:
swiftfunc tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "CellID", for: indexPath) cell.textLabel?.text = dataArray[indexPath.row].title return cell }
-
优化点:
- 避免在
cellForRow
中执行耗时操作(如网络请求)。 - 使用
prepareForReuse
清理旧数据。
- 避免在
三、多线程优化
1. 主线程任务最小化
-
原理:主线程阻塞导致 UI 卡顿(16ms 内未完成一帧绘制)。
-
Objective-C:
ini// 将耗时操作放到后台线程 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSData *data = [NSData dataWithContentsOfURL:url]; dispatch_async(dispatch_get_main_queue(), ^{ self.imageView.image = [UIImage imageWithData:data]; }); });
-
Swift:
csharpDispatchQueue.global(qos: .userInitiated).async { let data = try? Data(contentsOf: url) DispatchQueue.main.async { self.imageView.image = UIImage(data: data!) } }
2. 线程安全与锁优化
-
Objective-C:
-
@synchronized
实现简单但性能较低:objc
java@synchronized(self) { // 临界区 }
-
高性能场景使用
os_unfair_lock
(替代已废弃的OSSpinLock
):ini#include <os/lock.h> os_unfair_lock lock = OS_UNFAIR_LOCK_INIT; os_unfair_lock_lock(&lock); // 临界区 os_unfair_lock_unlock(&lock);
-
-
Swift:
-
使用
NSLock
或DispatchQueue
屏障:arduinolet queue = DispatchQueue(label: "com.example.threadSafe", attributes: .concurrent) queue.async(flags: .barrier) { // 写操作(独占访问) }
-
四、网络优化
1. 请求合并与缓存
-
Objective-C:
objectivec// 使用 NSURLSession 的缓存策略 NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:10];
-
Swift:
lesslet request = URLRequest(url: url, cachePolicy: .returnCacheDataElseLoad, timeoutInterval: 10)
-
优化点:
- 减少重复请求(如短时间内多次刷新)。
- 使用 HTTP/2 多路复用降低连接开销。
五、启动时间优化
1. 冷启动阶段优化
-
原理 :减少
main()
函数之前的加载时间(T1)和首帧渲染时间(T2)。 -
Objective-C:
- 减少动态库数量,合并 Category。
- 避免在
+load
方法中执行代码。
-
Swift:
-
使用
@UIApplicationMain
减少启动代码。 -
延迟非必要初始化:
javascriptDispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { // 延迟初始化第三方 SDK }
-
六、I/O 优化
1. 文件读写异步化
-
Objective-C:
arduinodispatch_io_t channel = dispatch_io_create_with_path(DISPATCH_IO_STREAM, [path UTF8String], O_RDONLY, 0, queue, ^(int error) {}); dispatch_io_read(channel, 0, SIZE_MAX, queue, ^(bool done, dispatch_data_t data, int error) {});
-
Swift:
arduinolet queue = DispatchQueue.global(qos: .background) DispatchIO.read(fromFileDescriptor: fd, queue: queue) { data, _ in // 处理数据 }
七、图像处理优化
1. 异步解码与降采样
-
Objective-C:
objectivec// 使用 ImageIO 进行降采样 CGImageSourceRef source = CGImageSourceCreateWithURL((__bridge CFURLRef)url, NULL); CGImageRef imageRef = CGImageSourceCreateImageAtIndex(source, 0, (__bridge CFDictionaryRef)@{(id)kCGImageSourceThumbnailMaxPixelSize: @(300)}); UIImage *image = [UIImage imageWithCGImage:imageRef];
-
Swift:
swiftlet source = CGImageSourceCreateWithURL(url as CFURL, nil)! let options: [CFString: Any] = [kCGImageSourceThumbnailMaxPixelSize: 300] let imageRef = CGImageSourceCreateThumbnailAtIndex(source, 0, options as CFDictionary)! let image = UIImage(cgImage: imageRef)
八、算法与数据结构
1. 高效遍历与查询
-
Objective-C:
- 使用
NSDictionary
替代NSArray
快速查找(O(1) vs O(n))。
- 使用
-
Swift:
-
使用
lazy
延迟计算集合:inilet filteredData = data.lazy.filter { $0.isValid }.map { $0.value }
-
使用
ContiguousArray
提升性能(连续内存布局)。
-
九、工具使用
1. Instruments 分析
- Time Profiler:定位 CPU 热点函数。
- Allocations:分析内存分配类型和泄漏。
- Core Animation:检测离屏渲染和帧率。
十、Swift 特有优化
1. 减少动态派发
-
使用
final
和private
修饰类或方法:swiftfinal class NetworkManager { private func fetchData() { ... } }
2. 值类型优先
-
使用结构体(
struct
)替代类(class
)减少引用计数开销:kotlinstruct Point { var x: Double var y: Double }
总结
- Objective-C 优化重点:手动内存管理、
@autoreleasepool
、避免performSelector
潜在泄漏。 - Swift 优化重点:值类型、协议扩展、
DispatchQueue
和现代语法(如Result
类型)。 - 通用原则:减少主线程阻塞、复用资源、异步化耗时操作、利用工具分析瓶颈。