在 VideoToolbox 中将 NSDictionary 转换为 CFDictionary
Converting NSDictionary to CFDictionary in 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
错误。为什么?
结果想再次访问时,把@{}
字面量放入CFDictionaryRef
后没有保留。所以下面的代码将起作用:
NSDictionary *dic = @{(NSString*)kCVPixelBufferPixelFormatTypeKey:@(kCVPixelFormatType_32BGRA)}; // "dic" reference will retain the nsdic created with @ literal
CFDictionaryRef destinationImageBufferAttrs = (__bridge CFDictionaryRef)dic;
在您的第一个代码示例中,存储在 destinationImageBufferAttrs
中的引用已被拥有,并且必须稍后使用 CFRelease
释放(或转移到 ARC 控制)。
在第二个代码示例中,存储到 destinationImageBufferAttrs
中的引用受 ARC 控制,ARC 可以在分配后立即释放它,因为不再有 ARC 拥有的引用。
将 __bridge
更改为 __bridge_retained
以将所有权从 ARC 转移到您自己的代码,然后您将负责为该对象调用 CFRelease
。
有什么区别
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
错误。为什么?
结果想再次访问时,把@{}
字面量放入CFDictionaryRef
后没有保留。所以下面的代码将起作用:
NSDictionary *dic = @{(NSString*)kCVPixelBufferPixelFormatTypeKey:@(kCVPixelFormatType_32BGRA)}; // "dic" reference will retain the nsdic created with @ literal
CFDictionaryRef destinationImageBufferAttrs = (__bridge CFDictionaryRef)dic;
在您的第一个代码示例中,存储在 destinationImageBufferAttrs
中的引用已被拥有,并且必须稍后使用 CFRelease
释放(或转移到 ARC 控制)。
在第二个代码示例中,存储到 destinationImageBufferAttrs
中的引用受 ARC 控制,ARC 可以在分配后立即释放它,因为不再有 ARC 拥有的引用。
将 __bridge
更改为 __bridge_retained
以将所有权从 ARC 转移到您自己的代码,然后您将负责为该对象调用 CFRelease
。