使用缓存
在 iOS 上使用 NSCache 可以有效减少主线程上的工作负担,特别是在需要频繁访问和重复计算的情况下。以下是一个简单的 SwiftUI 示例,展示如何在应用中使用 NSCache 来缓存图像以减少加载时间和主线程的负担。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| import SwiftUI
class ImageCache { static let shared = NSCache<NSString, UIImage>() }
struct AsyncImageView: View { let url: URL @State private var image: UIImage? = nil var body: some View { Group { if let image = image { Image(uiImage: image) .resizable() .scaledToFit() } else { ProgressView() .onAppear { loadImage() } } } } private func loadImage() { if let cachedImage = ImageCache.shared.object(forKey: url.absoluteString as NSString) { self.image = cachedImage return } DispatchQueue.global().async { if let data = try? Data(contentsOf: url), let loadedImage = UIImage(data: data) { ImageCache.shared.setObject(loadedImage, forKey: url.absoluteString as NSString) DispatchQueue.main.async { self.image = loadedImage } } } } }
struct ContentView: View { let imageUrl = URL(string: "https://www.example.com/image.jpg")! var body: some View { AsyncImageView(url: imageUrl) .frame(width: 300, height: 300) .padding() } }
@main struct CacheExampleApp: App { var body: some Scene { WindowGroup { ContentView() } } }
|
添加观察者
使用通知中心(NotificationCenter)来监听通知是一种常见的方式,可以有效地减少主线程的负担,从而提高应用的响应性。你可以通过添加观察者来监听特定的通知,并在接收到通知时再执行相应的操作,避免在主线程上一直等待,阻碍其它交互操作。以下是一个简单的 SwiftUI 示例,展示如何使用 NotificationCenter 来监听和处理通知。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| import SwiftUI import Combine
extension Notification.Name { static let customNotification = Notification.Name("customNotification") }
struct ContentView: View { @State private var value: Int = 0 private var notificationObserver: AnyCancellable? var body: some View { VStack { Text("Value: \(value)") .padding() Button("Increase Value") { NotificationCenter.default.post(name: .customNotification, object: nil, userInfo: ["newValue": value + 1]) } } .onAppear { notificationObserver = NotificationCenter.default.publisher(for: .customNotification) .sink { notification in if let newValue = notification.userInfo?["newValue"] as? Int { value = newValue } } } .onDisappear { notificationObserver?.cancel() } } }
@main struct MyApp: App { var body: some Scene { WindowGroup { ContentView() } } }
|
异步
为了避免主线程卡死,可以利用 Swift Concurrency 技术(如 async/await)将耗时的计算任务转移到后台线程执行,同时在任务完成后将结果更新到主线程上。下面是一个使用 Swift Concurrency 技术的 SwiftUI 示例,展示如何在后台线程执行预加载任务,并在主线程上更新 UI。
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| import SwiftUI
struct ContentView: View { @State private var data: String = "Loading..." var body: some View { VStack { Text(data) .padding() Button("Load Data") { Task { await loadData() } } } .onAppear { Task { await loadData() } } } func loadData() async { let result = await performHeavyTask() await MainActor.run { data = result } } func performHeavyTask() async -> String { try? await Task.sleep(nanoseconds: 2_000_000_000) return "Data Loaded" } }
@main struct MyApp: App { var body: some Scene { WindowGroup { ContentView() } } }
|
这个示例展示了如何使用 Swift Concurrency 技术将耗时任务移到后台线程执行,从而避免主线程卡顿,并在任务完成后安全地更新 UI。这样可以确保你的应用在执行复杂任务时依然保持流畅的用户体验。