如何使用C++操作macOS的UserDefaults?
在macOS上用C++操作UserDefaults的方案
针对你的需求,其实不需要额外找第三方C库——macOS本身提供了两种直接可行的方式,完全能满足用C操作UserDefaults的需求:
1. Objective-C++桥接(最直观的方案)
C和Objective-C可以直接混写(文件后缀用.mm),你可以封装一个纯C接口的类,内部调用NSUserDefaults的原生方法,这样既能利用NSUserDefaults的完整功能,又能在C++代码里无缝调用。
示例代码:
// UserDefaultsWrapper.h(纯C++头文件) #include <string> class UserDefaultsWrapper { public: static void setString(const std::string& key, const std::string& value); static std::string getString(const std::string& key, const std::string& defaultValue = ""); static void setInteger(const std::string& key, int value); static int getInteger(const std::string& key, int defaultValue = 0); static void synchronize(); };
// UserDefaultsWrapper.mm(Objective-C++实现) #include "UserDefaultsWrapper.h" #import <Foundation/Foundation.h> void UserDefaultsWrapper::setString(const std::string& key, const std::string& value) { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:[NSString stringWithUTF8String:value.c_str()] forKey:[NSString stringWithUTF8String:key.c_str()]]; } std::string UserDefaultsWrapper::getString(const std::string& key, const std::string& defaultValue) { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *value = [defaults stringForKey:[NSString stringWithUTF8String:key.c_str()]]; return value ? std::string([value UTF8String]) : defaultValue; } void UserDefaultsWrapper::setInteger(const std::string& key, int value) { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setInteger:value forKey:[NSString stringWithUTF8String:key.c_str()]]; } int UserDefaultsWrapper::getInteger(const std::string& key, int defaultValue) { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; return [defaults integerForKey:[NSString stringWithUTF8String:key.c_str()]]; } void UserDefaultsWrapper::synchronize() { [[NSUserDefaults standardUserDefaults] synchronize]; }
在你的C++代码里,只要包含头文件就能直接调用,编译时把.mm文件加入编译流程即可。
2. 使用CoreFoundation的C接口(纯C++无ObjC代码)
如果你不想写Objective-C代码,可以直接用NSUserDefaults底层依赖的CoreFoundation框架的C接口(CFPreferences系列函数),这些都是纯C API,能直接在C里调用,操作的是同一个UserDefaults存储。
示例代码:
#include <CoreFoundation/CoreFoundation.h> #include <string> void setUserDefaultsString(const std::string& key, const std::string& value) { CFStringRef cfKey = CFStringCreateWithCString(nullptr, key.c_str(), kCFStringEncodingUTF8); CFStringRef cfValue = CFStringCreateWithCString(nullptr, value.c_str(), kCFStringEncodingUTF8); CFPreferencesSetAppValue(cfKey, cfValue, CFGetBundleIdentifier(CFBundleGetMainBundle())); CFPreferencesAppSynchronize(CFGetBundleIdentifier(CFBundleGetMainBundle())); CFRelease(cfKey); CFRelease(cfValue); } std::string getUserDefaultsString(const std::string& key, const std::string& defaultValue) { CFStringRef cfKey = CFStringCreateWithCString(nullptr, key.c_str(), kCFStringEncodingUTF8); CFStringRef cfValue = (CFStringRef)CFPreferencesCopyAppValue(cfKey, CFGetBundleIdentifier(CFBundleGetMainBundle())); std::string result = defaultValue; if (cfValue) { const char* cStr = CFStringGetCStringPtr(cfValue, kCFStringEncodingUTF8); if (cStr) { result = cStr; } else { char buffer[256]; if (CFStringGetCString(cfValue, buffer, sizeof(buffer), kCFStringEncodingUTF8)) { result = buffer; } } CFRelease(cfValue); } CFRelease(cfKey); return result; }
注意编译时需要链接CoreFoundation框架(编译参数加-framework CoreFoundation)。
总结
这两种方案都是系统原生支持的,不需要额外引入第三方库。如果你的项目已经有ObjC代码或者可以接受ObjC++,第一种方案更易用;如果要纯C++代码,第二种方案更合适。
内容的提问来源于stack exchange,提问作者Matus
相关产品推荐
相关产品推荐

