11import Foundation
22
33#if canImport(CombineRuntime)
4- import CombineRuntime
4+ import CombineRuntime
55#endif
66
77internal struct AssociationKey < Value> {
8- fileprivate let address : UnsafeRawPointer
9- fileprivate let `default` : Value !
10-
11- /// Create an ObjC association key.
12- ///
13- /// - warning: The key must be uniqued.
14- ///
15- /// - parameters:
16- /// - default: The default value, or `nil` to trap on undefined value. It is
17- /// ignored if `Value` is an optional.
18- init ( default: Value ? = nil ) {
19- self . address = UnsafeRawPointer (
20- UnsafeMutablePointer< UInt8> . allocate( capacity: 1 )
21- )
22- self . default = `default`
23- }
24-
25- /// Create an ObjC association key from a `StaticString`.
26- ///
27- /// - precondition: `key` has a pointer representation.
28- ///
29- /// - parameters:
30- /// - default: The default value, or `nil` to trap on undefined value. It is
31- /// ignored if `Value` is an optional.
32- init ( _ key: StaticString , default: Value ? = nil ) {
33- assert ( key. hasPointerRepresentation)
34- self . address = UnsafeRawPointer ( key. utf8Start)
35- self . default = `default`
36- }
37-
38- /// Create an ObjC association key from a `Selector`.
39- ///
40- /// - parameters:
41- /// - default: The default value, or `nil` to trap on undefined value. It is
42- /// ignored if `Value` is an optional.
43- init ( _ key: Selector , default: Value ? = nil ) {
44- self . address = UnsafeRawPointer ( key. utf8Start)
45- self . default = `default`
46- }
8+ fileprivate let address : UnsafeRawPointer
9+ fileprivate let `default` : Value !
10+
11+ /// Create an ObjC association key.
12+ ///
13+ /// - warning: The key must be uniqued.
14+ ///
15+ /// - parameters:
16+ /// - default: The default value, or `nil` to trap on undefined value. It is
17+ /// ignored if `Value` is an optional.
18+ init ( default: Value ? = nil ) {
19+ self . address = UnsafeRawPointer (
20+ UnsafeMutablePointer< UInt8> . allocate( capacity: 1 )
21+ )
22+ self . default = `default`
23+ }
24+
25+ /// Create an ObjC association key from a `StaticString`.
26+ ///
27+ /// - precondition: `key` has a pointer representation.
28+ ///
29+ /// - parameters:
30+ /// - default: The default value, or `nil` to trap on undefined value. It is
31+ /// ignored if `Value` is an optional.
32+ init ( _ key: StaticString , default: Value ? = nil ) {
33+ assert ( key. hasPointerRepresentation)
34+ self . address = UnsafeRawPointer ( key. utf8Start)
35+ self . default = `default`
36+ }
37+
38+ /// Create an ObjC association key from a `Selector`.
39+ ///
40+ /// - parameters:
41+ /// - default: The default value, or `nil` to trap on undefined value. It is
42+ /// ignored if `Value` is an optional.
43+ init ( _ key: Selector , default: Value ? = nil ) {
44+ self . address = UnsafeRawPointer ( key. utf8Start)
45+ self . default = `default`
46+ }
4747}
4848
4949internal struct Associations < Base: AnyObject > {
50- fileprivate let base : Base
51-
52- init ( _ base: Base ) {
53- self . base = base
54- }
50+ fileprivate let base : Base
51+
52+ init ( _ base: Base ) {
53+ self . base = base
54+ }
5555}
5656
5757extension NSObjectProtocol {
58- /// Retrieve the associated value for the specified key. If the value does not
59- /// exist, `initial` would be called and the returned value would be
60- /// associated subsequently.
61- ///
62- /// - parameters:
63- /// - key: An optional key to differentiate different values.
64- /// - initial: The action that supples an initial value.
65- ///
66- /// - returns: The associated value for the specified key.
67- internal func associatedValue< T> (
68- forKey key: StaticString = #function,
69- initial: ( Self ) -> T
70- ) -> T {
71- let key = AssociationKey < T ? > ( key)
72-
73- if let value = associations. value ( forKey: key) {
74- return value
75- }
76-
77- let value = initial ( self )
78- associations. setValue ( value, forKey: key)
79-
80- return value
81- }
58+ /// Retrieve the associated value for the specified key. If the value does not
59+ /// exist, `initial` would be called and the returned value would be
60+ /// associated subsequently.
61+ ///
62+ /// - parameters:
63+ /// - key: An optional key to differentiate different values.
64+ /// - initial: The action that supples an initial value.
65+ ///
66+ /// - returns: The associated value for the specified key.
67+ internal func associatedValue< T> (
68+ forKey key: StaticString = #function,
69+ initial: ( Self ) -> T
70+ ) -> T {
71+ let key = AssociationKey < T ? > ( key)
72+
73+ if let value = associations. value ( forKey: key) {
74+ return value
75+ }
76+
77+ let value = initial ( self )
78+ associations. setValue ( value, forKey: key)
79+
80+ return value
81+ }
8282}
8383
8484extension NSObjectProtocol {
85- @nonobjc internal var associations : Associations < Self > {
86- return Associations ( self )
87- }
85+ @nonobjc internal var associations : Associations < Self > {
86+ return Associations ( self )
87+ }
8888}
8989
9090extension Associations {
91- /// Retrieve the associated value for the specified key.
92- ///
93- /// - parameters:
94- /// - key: The key.
95- ///
96- /// - returns: The associated value, or the default value if no value has been
97- /// associated with the key.
98- internal func value< Value> (
99- forKey key: AssociationKey < Value >
100- ) -> Value {
101- return ( objc_getAssociatedObject ( base, key. address) as! Value ? ) ?? key. default
102- }
103-
104- /// Retrieve the associated value for the specified key.
105- ///
106- /// - parameters:
107- /// - key: The key.
108- ///
109- /// - returns: The associated value, or `nil` if no value is associated with
110- /// the key.
111- internal func value< Value> (
112- forKey key: AssociationKey < Value ? >
113- ) -> Value ? {
114- return objc_getAssociatedObject ( base, key. address) as! Value ?
115- }
116-
117- /// Set the associated value for the specified key.
118- ///
119- /// - parameters:
120- /// - value: The value to be associated.
121- /// - key: The key.
122- internal func setValue< Value> (
123- _ value: Value ,
124- forKey key: AssociationKey < Value >
125- ) {
126- objc_setAssociatedObject ( base, key. address, value, . OBJC_ASSOCIATION_RETAIN_NONATOMIC)
127- }
128-
129- /// Set the associated value for the specified key.
130- ///
131- /// - parameters:
132- /// - value: The value to be associated.
133- /// - key: The key.
134- internal func setValue< Value> (
135- _ value: Value ? ,
136- forKey key: AssociationKey < Value ? >
137- ) {
138- objc_setAssociatedObject ( base, key. address, value, . OBJC_ASSOCIATION_RETAIN_NONATOMIC)
139- }
91+ /// Retrieve the associated value for the specified key.
92+ ///
93+ /// - parameters:
94+ /// - key: The key.
95+ ///
96+ /// - returns: The associated value, or the default value if no value has been
97+ /// associated with the key.
98+ internal func value< Value> (
99+ forKey key: AssociationKey < Value >
100+ ) -> Value {
101+ return ( objc_getAssociatedObject ( base, key. address) as! Value ? ) ?? key. default
102+ }
103+
104+ /// Retrieve the associated value for the specified key.
105+ ///
106+ /// - parameters:
107+ /// - key: The key.
108+ ///
109+ /// - returns: The associated value, or `nil` if no value is associated with
110+ /// the key.
111+ internal func value< Value> (
112+ forKey key: AssociationKey < Value ? >
113+ ) -> Value ? {
114+ return objc_getAssociatedObject ( base, key. address) as! Value ?
115+ }
116+
117+ /// Set the associated value for the specified key.
118+ ///
119+ /// - parameters:
120+ /// - value: The value to be associated.
121+ /// - key: The key.
122+ internal func setValue< Value> (
123+ _ value: Value ,
124+ forKey key: AssociationKey < Value >
125+ ) {
126+ objc_setAssociatedObject ( base, key. address, value, . OBJC_ASSOCIATION_RETAIN_NONATOMIC)
127+ }
128+
129+ /// Set the associated value for the specified key.
130+ ///
131+ /// - parameters:
132+ /// - value: The value to be associated.
133+ /// - key: The key.
134+ internal func setValue< Value> (
135+ _ value: Value ? ,
136+ forKey key: AssociationKey < Value ? >
137+ ) {
138+ objc_setAssociatedObject ( base, key. address, value, . OBJC_ASSOCIATION_RETAIN_NONATOMIC)
139+ }
140140}
141141
142142/// Set the associated value for the specified key.
@@ -146,14 +146,14 @@ extension Associations {
146146/// - key: The key.
147147/// - address: The address of the object.
148148internal func unsafeSetAssociatedValue< Value> (
149- _ value: Value ? ,
150- forKey key: AssociationKey < Value > ,
151- forObjectAt address: UnsafeRawPointer
149+ _ value: Value ? ,
150+ forKey key: AssociationKey < Value > ,
151+ forObjectAt address: UnsafeRawPointer
152152) {
153- _combineRuntimeSetAssociatedObject (
154- address,
155- key. address,
156- value,
157- . OBJC_ASSOCIATION_RETAIN_NONATOMIC
158- )
153+ _combineRuntimeSetAssociatedObject (
154+ address,
155+ key. address,
156+ value,
157+ . OBJC_ASSOCIATION_RETAIN_NONATOMIC
158+ )
159159}
0 commit comments