Array could be potentially converted to UnsafePointer in Swift, why?

Owen Zhao :

I have code

extension CGColor {
    static func color(from color:Color) -> CGColor {
        let (r, g, b) = try! retrieveRGB(from: color.in16bitString)
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let array = [r, g, b, CGFloat(color.alpha)]
        let unsafePointer = UnsafePointer(array)

        return CGColor(colorSpace: colorSpace, components: unsafePointer)!
    }

    private static func retrieveRGB(from in16bitString:String) throws -> (CGFloat, CGFloat, CGFloat) {
        ...
    }
}

which shows warnings on line "let unsafePointer = UnsafePointer(array)", saying "Initialization of 'UnsafePointer' results in a dangling pointer".

I posted a question but was filed as duplicated to UnsafeMutablePointer Warning with Swift 5. Those answers don't help. As Apple API request a UnsafePointer as a parameter.

However, I finally found that just using the array alone works.

extension CGColor {
    static func color(from color:Color) -> CGColor {
        let (r, g, b) = try! retrieveRGB(from: color.in16bitString)
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let array = [r, g, b, CGFloat(color.alpha)]

        return CGColor(colorSpace: colorSpace, components: array)!
    }

    private static func retrieveRGB(from in16bitString:String) throws -> (CGFloat, CGFloat, CGFloat) {
        ...
    }
}

Does anyone know why I could use an Array when a UnsafePointer is requested?

Alexander - Reinstate Monica :

Swift's memory model only guarantees that objects will stick around until at least their last use, and not necessarily any longer. This is different from C and C++ for example, where objects stay until the end of the scope.

let unsafePointer = UnsafePointer(array) doesn't work, because this initializer call is the last usage of array. After that initializer returns, Swift is free to deallocate array, because it doesn't know that there's a relationship between UnsafePointer is dependant on array.

Does anyone know why I could use an Array when a UnsafePointer is requested?

It's one of Swift's implicit conversion rules. A pointer to the array's buffer is passed in (note, that's different from a pointer to the array struct, itself), and the lifetime of array is guaranteed to last until the end of the call. It could cause a bug, if that function tries to save the pointer for later user (by which point the array could have been deallocated).

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=376155&siteId=1