ARC не работает в Objective-Stack Overflow

У меня есть функция C ++, которая получает std::map объект и преобразовать его в CFMutableDisctionryRef чтобы использовать его на метод CFNotificationCenterPostNotification, Вот моя реализация:

void IPCNotificationSender::send(const char *identifier, map<const char *, const char *> dict)
{
NSMutableDictionary *myDict = [NSMutableDictionary dictionary];

CFStringRef cfIdentifier = CFStringCreateWithCString(NULL, identifier,
kCFStringEncodingMacRoman);
for (std::map<const char *, const char *>::iterator it=dict.begin(); it!=dict.end(); ++it)
{
NSString *key = [NSString stringWithUTF8String:it->first];
NSString *val = [NSString stringWithUTF8String:it->second];
myDict[key] = key;
}
CFMutableDictionaryRef myCFDict = (CFMutableDictionaryRef)CFBridgingRetain(myDict);

CFNotificationCenterPostNotification(CFNotificationCenterGetDistributedCenter(), cfIdentifier, NULL, myCFDict, TRUE);

CFRelease(myCFDict);
CFRelease(cfIdentifier);
}

Тем не менее, кажется, что утечка памяти в NSString *key объект, где он должен быть освобожден автоматически. Я попытался реализовать преобразование поверх целевого типа функции C и все еще получил те же результаты … Я склонен полагать, что сочетание между c ++ и target-C, хотя и допустимо, вызывает некоторые проблемы с мусором target-c коллектор.

Где я ошибся в своей реализации?

Спасибо

2

Решение

Проблемы с С ++:

  • эта карта выглядит плохо. так должно быть map<string, string>
  • вы передаете карту по значению, а не по постоянному отношению

Задача C проблема:

Основываясь на подсказках, которые дают принятый ответ, я подозреваю, в чем тут проблема.
Ваш код C ++ работает непрерывно без достижения пула автоматического выпуска. Поэтому, когда вы используете Objective C API, где задействован пул автоматического выпуска, эти объекты не освобождаются, поскольку пул автоматического выпуска никогда не получает контроль.

Так что я бы написал это так:

NSString *ConvertToObjC(const string& s)
{
return [NSString stringWithUTF8String: s.c_str()];
}

NSDictionary *ConvertToObjC(const map<string, string>& cppMap)
// here I use templates which do lots of magic, but this is off topic,
{
NSMutableDictionary *result = [NSMutableDictionary dictionaryWithCapacity: cppMap.count()];

for (const auto& x : cppMap)
{
result[ConvertToObjC(x.first)] = ConvertToObjC(x.second);
}

return result;
}

void IPCNotificationSender::send(const string& identifier,
const map<string, string>& cppMap)
{
@autoreleasepool {
auto ident = ConvertToObjC(identifier);
auto myDic = ConvertToObjC(cppMap);

CFNotificationCenterPostNotification(
CFNotificationCenterGetDistributedCenter(),
(CFStringRef)CFBridgingRetain(ident),
NULL,
(CFDictionaryRef)CFBridgingRetain(myDict),
TRUE);
}
}
2

Другие решения

Я наткнулся на ту же проблему, кажется, проблемное поведение управления памятью в общих проектах C ++ / Objective C.

Решение было создать объекты, которые вы можете вручную освободить их.

В своем коде попробуйте следующее:

 for (std::map<const char *, const char *>::iterator it=dict.begin(); it!=dict.end(); ++it)
{
CFStringRef key = CFStringCreateWithCString(NULL, it->first,
kCFStringEncodingMacRoman);
CFStringRef val = CFStringCreateWithCString(NULL, it->second,
kCFStringEncodingMacRoman);

myDict[(__bridge NSString *  _Nonnull __strong)(key)] = (__bridge NSString *  _Nonnull __strong)(val);

CFRelease(key);
CFRelease(val);
}
2

По вопросам рекламы [email protected]