Когда вы должны использовать __bridge против CFBridgingRelease/CFBridgingRetain?
У меня есть этот код, который использует "__bridge" для отображения идентификаторов цветов:
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);
но будет:
NSArray *colors = [NSArray arrayWithObjects:(id)CFBridgingRelease(startColor), (id)CFBridgingRelease(endColor), nil];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)CFBridgingRetain(colors), locations);
- лучшее решение?
Ответы
Ответ 1
Вы не "владеете" объектами Core Foundation startColor
, endColor
, потому что они были
не возвращается функцией, которая имеет "Создать" или "Копировать" в ее имени (сравните "Создать правило" в "Руководстве по программированию памяти для Core Foundation".
И поскольку вы не владеете объектами, вы не должны "передавать права собственности" в ARC с помощью
CFBridgingRelease()
. Так
[NSArray arrayWithObjects:(__bridge id)startColor, (__bridge id)endColor, nil];
является правильным. И
CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);
также правильна, потому что
CGGradientCreateWithColors(colorSpace, (CFArrayRef)CFBridgingRetain(colors), locations);
передал (+1) сохраненный массив в CGGradientCreateWithColors()
. Это будет память
поскольку эта функция не освобождает аргумент colors
.
Ответ 2
С NSURL - та же проблема
NSString *soundPath = [[NSBundle mainBundle] pathForResource:@"sound" ofType:@"wav"];
NSURL *soundURL = [NSURL fileURLWithPath:soundPath];
AudioServicesCreateSystemSoundID(CFBridgingRetain(soundURL), &soundEffect);