SecCopyErrorMessageString leaks memory

SecCopyErrorMessageString suggests that the return value should be called with CFRelease to release/free the object.

Though upon attempting to do so, XCode says "CFRelease is unavailable: Core Foundation objects are automatically memory managed".

I have verified with Instruments in XCode that the follow code increases in memory usage without bound, from ~3MB to 20MB+ over 100000 iterations.

public func simpleLeak(){
        var secReq: SecRequirement?
        let err = SecRequirementCreateWithString("blah" as CFString, SecCSFlags(rawValue: 0), &secReq)
        guard err == errSecSuccess else {
            var errorString = SecCopyErrorMessageString(err, nil)
            print(errorString)
            return
        }
    }

What's the proper usage of SecCopyErrorMessageString that doesn't leak memory in Swift?

Answered by DTS Engineer in 751808022

SecCopyErrorMessageString has been annotated for ARC [1] and thus you don’t need to release its result. You can tell because it’s imported into Swift as:

func SecCopyErrorMessageString(_ status: OSStatus, _ reserved: UnsafeMutableRawPointer?) -> CFString?

If it weren’t so annotated the result would be an Unmanaged<CFString>. It’s this Unmanaged wrapper that lets you release the result.

I have verified with Instruments in Xcode that the follow code increases in memory usage without bound, from ~3MB to 20MB+ over 100000 iterations.

Are you sure that’s SecCopyErrorMessageString leaking and not SecRequirementCreateWithString?

Are you sure you’re leaking and not accumulating references in the autorelease pool. See Objective-C Memory Management for Swift Programmers.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Not directly, but implicitly via the CF_IMPLICIT_BRIDGING_ENABLED at the top of the <Security/SecBase.h> header.

Accepted Answer

SecCopyErrorMessageString has been annotated for ARC [1] and thus you don’t need to release its result. You can tell because it’s imported into Swift as:

func SecCopyErrorMessageString(_ status: OSStatus, _ reserved: UnsafeMutableRawPointer?) -> CFString?

If it weren’t so annotated the result would be an Unmanaged<CFString>. It’s this Unmanaged wrapper that lets you release the result.

I have verified with Instruments in Xcode that the follow code increases in memory usage without bound, from ~3MB to 20MB+ over 100000 iterations.

Are you sure that’s SecCopyErrorMessageString leaking and not SecRequirementCreateWithString?

Are you sure you’re leaking and not accumulating references in the autorelease pool. See Objective-C Memory Management for Swift Programmers.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Not directly, but implicitly via the CF_IMPLICIT_BRIDGING_ENABLED at the top of the <Security/SecBase.h> header.

Sorry for the delayed response. Thank you Eskimo!

SecCopyErrorMessageString leaks memory
 
 
Q