I am unsure whether to use CF_RETURNS_RETAINED or CF_RETURNS_NOT_RETAINED for my custom function returning a CFDataProviderRef
.
According to the documentation at the location where the macros are defined, both should only used in exceptional circumstances, and the correct fix should be to fix my naming convention. However The swift/objective-c documentation suggests using them to annotate any function returning a CoreFoundation pointer, without really explaining when to use which --- if I don't annotate them I need to manually specify the behaviour every time in the swift code.
Further documentation I could find explains how one uses a ARC value of +1 and the other of 0, however I'm afraid that doesn't help me much in understanding.
My questions:
Base.h
suggests?CFDataProviderRef
that I got from a call to CGDataProviderCreateSequential
. I guess that means I want the the behaviour as CGDataProviderCreateSequential
(right?). How can I find whether that function uses CF_RETURNS_RETAINED or CF_RETURNS_NOT_RETAINED (it's not there in the CGDataProvider.h
file)?This is all about ownership. The naming convention is that of Core Foundation, which is described here. The Create Rule says that functions with "Create" and "Copy" in their name leave the caller with ownership of the returned object (although not necessarily sole ownership). That means that the caller has a responsibility to eventually release the returned object using CFRelease()
. The Get Rule says that functions other than creation or copy functions do not give the caller ownership of the object, so the caller must not call CFRelease()
on it (except to balance any explicit calls to CFRetain()
, of course).
If a function is semantically a creation or copy function which returns ownership to the caller, but its name doesn't indicate that, you should use CF_RETURNS_RETAINED
to indicate that. Similarly, if a function's name contains "Create" or "Copy" but it doesn't have semantics matching the Create Rule, you should use CF_RETURNS_NOT_RETAINED
to indicate that. (Try to avoid this.)
Since your code is calling CGDataProviderCreateSequential()
and since that has "Create" in the name, your code is responsible for releasing the returned CGDataProvider
object. If you release it right there in your function, then your caller can't get access to it. You want to return the object to the caller. You also want to pass the responsibility for releasing the object to the caller, since you don't know when the caller will be done with it. So, you should name your function with "Create" in its name to indicate both to the caller and to automated systems that the caller receives responsibility for releasing the object. Alternatively, you could annotate your function with CF_RETURNS_RETAINED
to signify that, but following the naming convention is better.
It's possible that Swift only respects the naming convention for system headers. I don't know. In that case, you'd have to annotate with CF_RETURNS_RETAINED
even if your function has "Create" in its name. There's no harm in annotating a function whose name already follows the convention. It's redundant but harmless.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With