杨锴
2025-04-16 09a372bc45fde16fd42257ab6f78b8deeecf720b
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
71
72
73
//
//  SerialDisposable.swift
//  RxSwift
//
//  Created by Krunoslav Zaher on 3/12/15.
//  Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
 
/// Represents a disposable resource whose underlying disposable resource can be replaced by another disposable resource, causing automatic disposal of the previous underlying disposable resource.
public final class SerialDisposable : DisposeBase, Cancelable {
    private var lock = SpinLock()
    
    // state
    private var current = nil as Disposable?
    private var disposed = false
    
    /// - returns: Was resource disposed.
    public var isDisposed: Bool {
        self.disposed
    }
    
    /// Initializes a new instance of the `SerialDisposable`.
    override public init() {
        super.init()
    }
    
    /**
    Gets or sets the underlying disposable.
    
    Assigning this property disposes the previous disposable object.
    
    If the `SerialDisposable` has already been disposed, assignment to this property causes immediate disposal of the given disposable object.
    */
    public var disposable: Disposable {
        get {
            self.lock.performLocked {
                self.current ?? Disposables.create()
            }
        }
        set (newDisposable) {
            let disposable: Disposable? = self.lock.performLocked {
                if self.isDisposed {
                    return newDisposable
                }
                else {
                    let toDispose = self.current
                    self.current = newDisposable
                    return toDispose
                }
            }
            
            if let disposable = disposable {
                disposable.dispose()
            }
        }
    }
    
    /// Disposes the underlying disposable as well as all future replacements.
    public func dispose() {
        self._dispose()?.dispose()
    }
 
    private func _dispose() -> Disposable? {
        self.lock.performLocked {
            guard !self.isDisposed else { return nil }
 
            self.disposed = true
            let current = self.current
            self.current = nil
            return current
        }
    }
}