ARC 在 Objective-C++ 中不起作用
ARC doesn't work in Objective-C++
我有一个 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
对象中似乎存在内存泄漏,应该自动释放它。我尝试在 objective-C 函数类型之上实现转换,但仍然得到相同的结果......我倾向于认为 c++ 和 objective-C 之间的混合虽然有效,但会导致一些问题objective-c 垃圾收集器。
我的实现哪里出错了?
感谢
我遇到了同样的问题,共享 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);
}
C++ 问题:
- 这张地图看起来很糟糕。应该是
map<string, string>
- 您是按值而不是常量关系传递地图
Objective 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++ 函数,它获取 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
对象中似乎存在内存泄漏,应该自动释放它。我尝试在 objective-C 函数类型之上实现转换,但仍然得到相同的结果......我倾向于认为 c++ 和 objective-C 之间的混合虽然有效,但会导致一些问题objective-c 垃圾收集器。
我的实现哪里出错了?
感谢
我遇到了同样的问题,共享 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);
}
C++ 问题:
- 这张地图看起来很糟糕。应该是
map<string, string>
- 您是按值而不是常量关系传递地图
Objective 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);
}
}