Melting Values

Let a value invalidate x-seconds after it has been set. Usable if information has not to be hold on all the time (like a timeout message or something)

class Melt<Element> {
    var value: Element? {
        didSet {
            self.timer?.invalidate()
            
            self.timer = Timer.scheduledTimer(
                timeInterval: self.lifetime, 
                target: self, 
                selector: #selector(invalidate), 
                userInfo: nil, 
                repeats: false
            )
        }
    }
    
    private let lifetime: TimeInterval
    
    init(_ lifetime: TimeInterval) {
        self.lifetime = lifetime
    }
    
    private var timer: Timer?
    @objc private func invalidate() {
        self.value = nil
        self.timer?.invalidate()
    }
}

Example:

var str = Melt<String>(4)
str.value = "Hello world"

DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: {
    print("Should be nil -> \(str.value ?? "nil")")
})

If you want you can make the lifetime variable and accessible so it can be changed dynamically (will not modify running timers in any way in the current setup).