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?
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.