Преобразование NSDictionary в CFDictionary в VideoToolbox

В чем разница между

const void *keys[] = { kCVPixelBufferPixelFormatTypeKey };
OSStatus pixelFormatType = kCVPixelFormatType_32BGRA;
CFNumberRef pixelFormatTypeRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pixelFormatType);
const void *values[] = { pixelFormatTypeRef };
CFDictionaryRef destinationImageBufferAttrs = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 1, NULL, NULL);

а также

CFDictionaryRef destinationImageBufferAttrs = (__bridge CFDictionaryRef)(@{(NSString*)kCVPixelBufferPixelFormatTypeKey:@(kCVPixelFormatType_32BGRA)});

?

Я получаю EXC_BAD_ACCESS ошибка, если я использую второй. Зачем?

2 ответа

Решение

В вашем первом примере кода ссылка хранится в destinationImageBufferAttrs принадлежит и должен быть позже выпущен с использованием CFRelease (или передан в управление ARC).

Во втором примере кода ссылка хранится в destinationImageBufferAttrs находится под контролем ARC, и ARC может освободить его сразу после назначения, так как на него больше нет ссылок, принадлежащих ARC.

+ Изменить __bridge в __bridge_retained чтобы передать право собственности с ARC на ваш собственный код, вы будете отвечать за CFRelease для объекта.

Оказалось, что @{} буквальный не был сохранен после помещения в CFDictionaryRef когда я хотел получить доступ снова. Поэтому ниже код будет работать вместо:

NSDictionary *dic = @{(NSString*)kCVPixelBufferPixelFormatTypeKey:@(kCVPixelFormatType_32BGRA)}; // "dic" reference will retain the nsdic created with @ literal
CFDictionaryRef destinationImageBufferAttrs = (__bridge CFDictionaryRef)dic;
Другие вопросы по тегам