views:

147

answers:

1

Running the static analyzer on this piece of code:

- (id) readForeignPref
{
 CFPropertyListRef matchStyle = CFPreferencesCopyAppValue(CFSTR("PBXFindMatchStyle"), CFSTR("com.apple.Xcode"));
 return [(id)matchStyle autorelease];
}

yields the following warning:

Call to function 'CFPreferencesCopyAppValue' returns a Core Foundation object with a +1 retain count (owning reference). Core Foundation objects are not automatically garbage collected.

Is this a warning I should fix with somethin ugly like that:

- (id) readForeignPref
{
 CFPropertyListRef matchStyle = CFPreferencesCopyAppValue(CFSTR("PBXFindMatchStyle"), CFSTR("com.apple.Xcode"));
 id nsMatchStyle = [(id)matchStyle copy];
 if (matchStyle) {
  CFRelease(matchStyle);
 }
 return [nsMatchStyle autorelease];
}

or is this just a false positive, given that the copied object is toll-free bridged?

+8  A: 

Try this:

- (id) readForeignPref
{
      CFPropertyListRef matchStyle = CFPreferencesCopyAppValue(CFSTR("PBXFindMatchStyle"), CFSTR("com.apple.Xcode"));
      return [(id)CFMakeCollectable(matchStyle) autorelease];
}

Without the CFMakeCollectable, this will leak in GC, because a CFRetain is different than an ObjC -retain. A CFRetain disables garbage collection of that object, and needs CFMakeCollectable to enable it.

kperryua
Instead of casting CFMakeCollectable(), use NSMakeCollectable(). But apart from that, kperryua’s answer is correct. See also: http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/GarbageCollection/Articles/gcCoreFoundation.html
Ahruman
CFMakeCollectable just CFRelease's the CF object. Since the object was allocated from the GC zone, the collector will always manage CF objects with a 0 retain count. (Implementation detail, but... there you have it)
bbum