使用缓存
在 iOS 上使用 NSCache 可以有效减少主线程上的工作负担,特别是在需要频繁访问和重复计算的情况下。以下是一个简单的 SwiftUI 示例,展示如何在应用中使用 NSCache 来缓存图像以减少加载时间和主线程的负担。
示例代码:
| 12
 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 来监听和处理通知。
示例代码:
| 12
 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 SwiftUIimport 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。
示例代码
| 12
 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。这样可以确保你的应用在执行复杂任务时依然保持流畅的用户体验。