0Pricing
Swift Academy · Lektion

Gängige Wrapper-Muster (Validierung, Caching)

Erstellen Sie gängige Wrapper für validation und caching : Prüfen Sie Eingaben, stellen Sie Standardwerte bereit, speichern Sie aufwendige Berechnungen zwischen und geben Sie Hilfsflags über projizierte Werte aus.

Gängige Wrapper-Muster (Validierung, Caching) ist eine kostenlose Swift Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 3. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Swift Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Swift Academy-Kurs umfasst insgesamt 3 Lektionen.

Was wir erstellen

Diese Lektion zeigt zwei praktische Muster:

  • Validierung: Eingaben akzeptieren oder mit Standardwerten und Meldungen korrigieren.
  • Caching: Ergebnisse speichern und über $helpers Funktionen wie clear() und isCached bereitstellen.

Validierung: NonEmpty

@NonEmpty fängt leere Eingaben ab und liefert einen Standardwert. Der projectedValue gibt an, ob die letzte Zuweisung automatisch korrigiert wurde.

@propertyWrapper
struct NonEmpty {
    private var value: String = ""
    private(set) var lastFixed: Bool = false

    var wrappedValue: String {
        get { value }
        set {
            if newValue.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
                value = "N/A"          // default fallback
                lastFixed = true
            } else {
                value = newValue
                lastFixed = false
            }
        }
    }

    var projectedValue: Bool { lastFixed } // $name -> was fixed?

    init(wrappedValue: String) { self.wrappedValue = wrappedValue }
}

struct Profile {
    @NonEmpty var displayName: String = "  "
}
var p = Profile()
print(p.displayName)  // "N/A"
print(p.$displayName) // true (was fixed)

Validierung: regelbasiert

@Validated ist generisch und akzeptiert eine Regel-Closure sowie einen Fallback. Verwenden Sie es für Längen-, Bereichs- oder benutzerdefinierte Prüfungen.

@propertyWrapper
struct Validated<Value> {
    private var value: Value
    private let rule: (Value) -> Bool
    private let fallback: Value
    private(set) var lastValid: Bool = true

    var wrappedValue: Value {
        get { value }
        set {
            if rule(newValue) {
                value = newValue
                lastValid = true
            } else {
                value = fallback
                lastValid = false
            }
        }
    }

    var projectedValue: Bool { lastValid } // $prop -> is valid?

    init(wrappedValue: Value, rule: @escaping (Value) -> Bool, fallback: Value) {
        self.rule = rule
        self.fallback = fallback
        self.value = wrappedValue
        self.lastValid = rule(wrappedValue)
        if !lastValid { self.value = fallback }
    }
}

struct Form {
    @Validated(rule: { $0.count >= 3 }, fallback: "???")
    var nickname: String = "hi"
}
var f = Form()
print(f.nickname)   // "???" (invalid -> fallback)
print(f.$nickname)  // false

Caching: verzögerte Memoisierung

@LazyCached memoisiert einen Wert aus einer Closure. $result stellt die Hilfsfunktionen isCached und clear() bereit.

@propertyWrapper
struct LazyCached<Value> {
    private var storage: Value?
    private let build: () -> Value

    var wrappedValue: Value {
        mutating get {
            if let v = storage { return v }         // hit
            let v = build()                         // miss -> compute
            storage = v
            return v
        }
        // Optional: allow manual set to override cache
        set { storage = newValue }
    }

    struct Controls {
        private let getter: () -> Bool
        private let clearer: () -> Void
        var isCached: Bool { getter() }
        func clear() { clearer() }
    }

    var projectedValue: Controls {
        Controls(
            getter: { self.storage != nil },
            clearer: { self.storage = nil }
        )
    }

    init(_ build: @escaping () -> Value) {
        self.build = build
        self.storage = nil
    }
}

// Demo: expensive computation (simulated)
var calls = 0
func heavy() -> Int { calls += 1; return (1...10_000).reduce(0, +) }

struct Engine {
    @LazyCached(heavy) var result: Int
}
var e = Engine()
print(e.$result.isCached) // false
print(e.result)           // computes once
print(e.result)           // uses cache
print(calls)              // 1

Caching: TTL-basiert

@TimedCache aktualisiert den Wert nach Ablauf einer TTL. Der projected value kann age bereitstellen, damit die aufrufende Stelle entscheiden kann, wann eine Aktualisierung erforderlich ist.

@propertyWrapper
struct TimedCache<Value> {
    private var storage: Value?
    private var timestamp: Date?
    private let ttl: TimeInterval
    private let build: () -> Value

    var wrappedValue: Value {
        mutating get {
            let now = Date()
            if let t = timestamp, let v = storage, now.timeIntervalSince(t) < ttl {
                return v                              // fresh
            }
            let v = build()                           // refresh
            storage = v
            timestamp = now
            return v
        }
    }

    struct Status { let age: TimeInterval? }
    var projectedValue: Status {
        let age = timestamp.map { Date().timeIntervalSince($0) }
        return Status(age: age)
    }

    init(ttl: TimeInterval, _ build: @escaping () -> Value) {
        self.ttl = ttl
        self.build = build
    }
}

// Demo (age only; TTL behavior depends on real time)
struct Stats {
    @TimedCache(ttl: 60) { Int.random(in: 0...1000) } var score: Int
}
var s2 = Stats()
print(s2.score)         // computes
print(s2.$score.age ?? -1)

Richtlinien für das Design

Tipps zum Design:

  • Halten Sie die Validierung rein und vorhersehbar; melden Sie Korrekturen über $flags.
  • Halten Sie den Zustand beim Caching klein; stellen Sie clear() oder isCached bereit.
  • Bevorzugen Sie Initialisierungsargumente für Richtlinien wie Fallbacks und TTL.

Projected Helpers für Caching

Kurztest: Was sollte $value in einem Caching-Wrapper bereitstellen?

Zusammenfassung

Zusammenfassung: Verwenden Sie Wrapper, um Eingaben zu validieren (Standardwerte, Regeln) und aufwendige Ergebnisse zu cachen (verzögert, TTL-basiert). Legen Sie Steuerung und Status für übersichtliche Aufrufstellen in projectedValue ab.

Häufig gestellte Fragen

Ist die Lektion „Gängige Wrapper-Muster (Validierung, Caching)“ kostenlos?

Ja — der vollständige Text von „Gängige Wrapper-Muster (Validierung, Caching)“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Swift Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Swift Academy-Kurs umfasst insgesamt 3 Lektionen.

Was lerne ich in „Gängige Wrapper-Muster (Validierung, Caching)“?

Erstellen Sie gängige Wrapper für validation und caching : Prüfen Sie Eingaben, stellen Sie Standardwerte bereit, speichern Sie aufwendige Berechnungen zwischen und geben Sie Hilfsflags über projizie… Du übst Swift Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Swift Academy zu starten?

Keine Vorkenntnisse erforderlich. Swift Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 3.

Wie lange dauert die Lektion „Gängige Wrapper-Muster (Validierung, Caching)“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Swift Academy-Lektion Code schreiben und ausführen?

Ja. Jede Swift Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Wrapper und projectedValue erstellen
  2. Wiederverwendbarkeit und Einschränkungen
  3. Gängige Wrapper-Muster (Validierung, Caching)
← Zurück zu Swift Academy