Как использовать CFMutableDictionaryRef с ARC - PullRequest
4 голосов
/ 03 марта 2012

Это то, как вы должны использовать CFMutableDictionaryRef с ARC?

CFMutableDictionaryRef myDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
NSString *key = @"someKey";
NSNumber *value = [NSNumber numberWithInt: 1];
//ARC doesn't handle retains with CF objects so I have to specify CFBridgingRetain when setting the value
CFDictionarySetValue(myDict, (__bridge void *)key, CFBridgingRetain(value));
id dictValue = (id)CFDictionaryGetValue(myDict, (__bridge void *)key);
//the value is removed but not released in any way so I have to call CFBridgingRelease next
CFDictionaryRemoveValue(myDict, (__bridge void *)key);
CFBridgingRelease(dictValue);//no leak

1 Ответ

11 голосов
/ 03 марта 2012

Не используйте CFBridgingRetain и CFBridgingRelease здесь вообще.Кроме того, вам нужно использовать __bridge при приведении результата CFDictionaryGetValue.

CFMutableDictionaryRef myDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
NSString *key = @"someKey";
NSNumber *value = [NSNumber numberWithInt: 1];
CFDictionarySetValue(myDict, (__bridge void *)key, (__bridge void *)value);

id dictValue = (__bridge id)CFDictionaryGetValue(myDict, (__bridge void *)key);
CFDictionaryRemoveValue(myDict, (__bridge void *)key);

Нет необходимости в CFBridgingRetain, так как словарь все равно сохранит значение.И если вы не позвоните CFBridgingRetain, вам не нужно балансировать его с выпуском позже.

В любом случае, все гораздо проще, если вы просто создадите NSMutableDictionary, а затем, если вынужно CFMutableDictionary, разыграть его:

NSMutableDictionary *myDict = [NSMutableDictionary dictionary];
NSString *key = @"someKey";
NSNumber *value = [NSNumber numberWithInt: 1];
[myDict setObject:value forKey:key];

CFMutableDictionaryRef myCFDict = CFBridgingRetain(myDict);
// use myCFDict here
CFRelease(myCFDict);

Обратите внимание, что CFBridgingRetain может быть сбалансировано с помощью CFRelease;вам не нужно использовать CFBridgingRelease, если вам не нужен id, который он возвращает.Точно так же вы можете сбалансировать CFRetain с CFBridgingRelease.

...