I have this code that uses "__bridge" to cast the ids of colors:
CGColorRef tabColor = (5 == 5
? [UIColor blueColor].CGColor
: [UIColor greenColor].CGColor);
CGColorRef startColor = [UIColor whiteColor].CGColor;
CGColorRef endColor = tabColor;
NSArray *colors = [NSArray arrayWithObjects:(__bridge id)startColor, (__bridge id)endColor, nil];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);
but would:
NSArray *colors = [NSArray arrayWithObjects:(id)CFBridgingRelease(startColor), (id)CFBridgingRelease(endColor), nil];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)CFBridgingRetain(colors), locations);
be a better solution?
You don't "own" the Core Foundation objects startColor
, endColor
because they were
not returned by a function that has "Create" or "Copy" in its name (compare "The Create Rule" in the "Memory Management Programming Guide for Core Foundation".
And because you don't own the objects, you must not "transfer the ownership" to ARC with
CFBridgingRelease()
. So
[NSArray arrayWithObjects:(__bridge id)startColor, (__bridge id)endColor, nil];
is correct. And
CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);
is also correct because
CGGradientCreateWithColors(colorSpace, (CFArrayRef)CFBridgingRetain(colors), locations);
would pass a (+1) retained array to CGGradientCreateWithColors()
. This would be a memory
leak because that function does not release the colors
argument.
With NSURL is the same problem
NSString *soundPath = [[NSBundle mainBundle] pathForResource:@"sound" ofType:@"wav"];
NSURL *soundURL = [NSURL fileURLWithPath:soundPath];
AudioServicesCreateSystemSoundID(CFBridgingRetain(soundURL), &soundEffect);