Cocoanetics
Cocoanetics

Reputation: 8255

How to name and handle memory management on a function that returns a CFType

I have a project running on ARC (DTCoreText) and I want to implement a category method on UIFont that returns a matching CTFontRef. This is what I have so far:

@implementation UIFont (DTCoreText)

+ (UIFont *)fontWithCTFont:(CTFontRef)ctFont
{
    NSString *fontName = (__bridge_transfer NSString *)CTFontCopyName(ctFont, kCTFontPostScriptNameKey);
    CGFloat fontSize = CTFontGetSize(ctFont);
    return [UIFont fontWithName:fontName size:fontSize];
}

- (CTFontRef)CTFont
{
    CTFontRef newFont = CTFontCreateWithName((__bridge CFStringRef)self.fontName, self.pointSize, NULL);

    return newFont;
}

@end

Technically this returns a +1 reference since there is no autoreleasing CF objects.

In my code I am calling it like this:

- (void)replaceFont:(UIFont *)font inRange:(NSRange)range
{
    [self beginEditing];

    [self removeAttribute:(id)kCTFontAttributeName range:range];

    CTFontRef ctFont = [font CTFont];
    [self addAttribute:(id)kCTFontAttributeName value:CFBridgingRelease(ctFont) range:range];

    [self endEditing];
}

This goes without Analyze warning because of the CFBridgingRelease, but I am worried about the need for that not being clear to somebody from the name of the category method.

A different suggestion has been to use a C-function for the creation instead:

static CTFontRef CTFontCreateFromUIFont(UIFont *font)

That would be more obvious because of the Create in the name which tells the developer that he is getting a +1 reference.

So what is the "correct" way in your opinion? Any other suggestions?

Upvotes: 0

Views: 204

Answers (1)

Peter Hosey
Peter Hosey

Reputation: 96393

Another option would be to name the method something like createCTFont. I don't know whether the analyzer will consider that to imply CF's Create rule on a method; if it doesn't, you can add an annotation to explicitly declare that the method returns an ownership:

- (CTFontRef) createCTFont CF_RETURNS_RETAINED;

Naming the method this way should make the reader suspicious if no release follows the creation message, and the annotation will definitely make the analyzer suspicious in the same circumstance.

Upvotes: 2

Related Questions