Skip to content

Instantly share code, notes, and snippets.

@treastrain
Created March 29, 2024 16:58
Show Gist options
  • Save treastrain/cee21a1af3127c62123c8ac1560ce9c0 to your computer and use it in GitHub Desktop.
Save treastrain/cee21a1af3127c62123c8ac1560ce9c0 to your computer and use it in GitHub Desktop.
import SwiftUI
struct ContentView: View {
@StateObject private var object = Object()
var body: some View {
List(object.numbers, id: \.self) { number in
Text("Content \(number)")
}
.refreshable {
await object.update()
}
}
}
final class Object: ObservableObject {
@MainActor @Published var numbers: [Int] = [0]
func update() async {
try? await Task.sleep(for: .seconds(1))
await addNewNumber()
}
@MainActor
private func addNewNumber() {
numbers.append(Int.random(in: 0..<100))
}
}
@treastrain
Copy link
Author

treastrain commented Mar 29, 2024

Task.value を await するパターン

import SwiftUI

@MainActor
final class Object: ObservableObject {
    @Published var numbers: [Int] = [0]
    
    nonisolated func update() async {
        await Task { @MainActor in
            numbers.removeAll()
        }.value
        try? await Task.sleep(for: .seconds(1))
        await Task { @MainActor in
            numbers.append(Int.random(in: 0..<100))
        }.value
    }
}

struct ContentView: View {
    @StateObject private var object = Object()
    
    var body: some View {
        NavigationStack {
            List(object.numbers, id: \.self) { number in
                Text("Content \(number)")
            }
            .refreshable {
                await object.update()
            }
        }
    }
}

@shimastripe
Copy link

struct Quote: Codable, Identifiable {
    let text: String?
    let author: String?
    
    var id: String {
        text ?? ""
    }
}

@treastrain
Copy link
Author

メインスレッドをパンパンにして 画面描画にも影響させるコード

import Foundation
import SwiftUI

func unsafeSleep() {
    for n in 0..<Int.max {
        _ = sin(Double(n))
    }
}

@MainActor
final class Object: ObservableObject {
    @Published var numbers: [Int] = [0]
    
    func update() async {
        Task { @MainActor in
            numbers.removeAll()
        }
        do {
            // try await Task.sleep(for: .seconds(1))
            unsafeSleep()
            Task { @MainActor in
                numbers.append(Int.random(in: 0..<100))
            }
        } catch {
            print(error)
        }
    }
}

struct ContentView: View {
    @StateObject private var object = Object()
    
    var body: some View {
        NavigationStack {
            List(object.numbers, id: \.self) { number in
                Text("Content \(number)")
            }
            .refreshable {
                await object.update()
            }
        }
    }
}

@shimastripe
Copy link

struct ContentView: View, Equatable {
    static func == (lhs: ContentView, rhs: ContentView) -> Bool {
        true
    }
    @StateObject private var exploreVM = ExploreViewModel()
}

適切かちょっと怪しいけど、再描画を期待していない冗長な更新がきっかけでbodyの再描画が起きてしまうことを防ぐなら

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment