Подтвердить что ты не робот

Когда вы должны использовать __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);

- лучшее решение?

4b9b3361

Ответ 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);