@@ -34,7 +34,13 @@ public struct Unmanaged<Instance: AnyObject> {
34
34
public static func fromOpaque(
35
35
@_nonEphemeral _ value: UnsafeRawPointer
36
36
) -> Unmanaged {
37
- return Unmanaged ( _private: unsafeBitCast ( value, to: Instance . self) )
37
+ // NOTE: This function does NOT go through the init(_private:) initializer
38
+ // because it requires us to materialize a strong reference to 'Instance'.
39
+ // This materialization is enough to convince the compiler to add
40
+ // retain/releases which we want to avoid for the opaque pointer functions.
41
+ // 'Unmanaged<Instance>' is layout compatible with 'UnsafeRawPointer' and
42
+ // casting to that will not attempt to retain the reference held at 'value'.
43
+ unsafeBitCast ( value, to: Unmanaged< Instance> . self )
38
44
}
39
45
40
46
/// Unsafely converts an unmanaged class reference to a pointer.
@@ -48,7 +54,12 @@ public struct Unmanaged<Instance: AnyObject> {
48
54
/// - Returns: An opaque pointer to the value of this unmanaged reference.
49
55
@_transparent
50
56
public func toOpaque( ) -> UnsafeMutableRawPointer {
51
- return unsafeBitCast ( _value, to: UnsafeMutableRawPointer . self)
57
+ // NOTE: This function does not attempt to unsafeBitCast '_value' because
58
+ // that will get a strong reference temporary value who the compiler will
59
+ // try to retain/release. Use 'self' to avoid this. 'Unmanaged<Instance>' is
60
+ // layout compatible with 'UnsafeRawPointer' and casting from that will not
61
+ // attempt to retain the reference held at '_value'.
62
+ unsafeBitCast ( self , to: UnsafeMutableRawPointer . self)
52
63
}
53
64
54
65
/// Creates an unmanaged reference with an unbalanced retain.
0 commit comments