ARC 在 Objective-C++ 中不起作用

ARC doesn't work in Objective-C++

本文关键字:不起作用 Objective-C++ ARC      更新时间:2023-10-16

我有一个获得std::map对象的C 函数,并将其转换为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对象似乎存在内存泄漏,应在其中自动释放它。我试图在Objective-C功能类型上实施转换,并且仍然得到相同的结果...我倾向于相信C 和Objective-C之间的混合物虽然有效,但却引起了Objective-C垃圾的某些问题集电极。

我在实施中出错了哪里?

谢谢

c 问题:

  • 这张地图看起来很糟糕。它应该是map<string, string>
  • 您是按值传递的,而不是通过const rerence

目标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);
    }
}

我偶然发现了同一问题,在共享的C /目标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);
}