Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CFNumber macro for constants

Tags:

ios

Pretty sure the answer is No on this one, but it's painful enough I have to ask: Is there a CFNumber equivalent to CFString's CFSTR macro? To avoid this sort of thing:

char one = 1;
CFNumberRef cfONE = CFNumberCreate(kCFAllocatorDefault, kCFNumberCharType, &one);
if (cfONE != NULL) {
    ... finally I can compare something to the number 1! ...
    CFRelease(cfONE);
} else {
    // not likely, but possible, if you really want to be conservative
}

Note that I'm not using Objective-C in this particular code.

Eric

like image 515
Eric McNeill Avatar asked Mar 18 '26 13:03

Eric McNeill


2 Answers

If you plan on using this function multiple times, you could the static modifier and stop worrying about deallocation:

static CFNumberRef cfONE = NULL;
if (cfONE == NULL) {
    static char one = 1;
    cfONE = CFNumberCreate(kCFAllocatorDefault, kCFNumberCharType, &one);
    assert (cfONE != NULL); // Oh no, destroy the world!
}

//    ... finally I can compare something to the number 1! ...

So long as you have static, the static analyzer will leave you alone on the leak issue since it is an expected constant size memory allocation, O(1) rather than O(n) where n is the number of executions.

There are several ways to make this a macro. I came up with this lazy one:

#define CFNUMDEF(name, type, numberType, value) \
static CFNumberRef name = NULL; \
if ( name == NULL) { \
    static type val = value ;\
    name = CFNumberCreate(kCFAllocatorDefault, numberType , &val);\
    assert ( name != NULL); \
}

CFNUMDEF(cfONE, char, kCFNumberCharType, 1);
//    ... finally I can compare something to the number 1! ...
like image 158
Brian Nickel Avatar answered Mar 26 '26 17:03

Brian Nickel


CFSTR is a little different from your case

CFSTR() allows creation of compile-time constant CFStringRefs; the argument should be a constant C-string.

CFSTR(), not being a "Copy" or "Create" function, does not return a new reference for you. So, you should not release the return value. This is much like constant C or Pascal strings --- when you use "hello world" in a program, you do not free it.

Where as the object you create with CFNumberCreate will be owned by the caller so you may still want to keep the word create in the name to make this clear.

You could always make a helper function just to avoid passing the same arguments over and over

CFNumberRef PSNumberCreateWithChar(x)
{
  return CFNumberCreate(kCFAllocatorDefault, kCFNumberCharType, &x);
}
like image 26
Paul.s Avatar answered Mar 26 '26 17:03

Paul.s



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!