Objective c 在我的macOS应用程序中,我正在使用UserDefaults dictionaryRepresentation。有时我会得到未知编码的字符串。有什么建议吗?
我正在使用Objective-C应用程序,具体来说,我正在使用以下代码收集NSUserDefaults的字典表示:Objective c 在我的macOS应用程序中,我正在使用UserDefaults dictionaryRepresentation。有时我会得到未知编码的字符串。有什么建议吗?,objective-c,nsstringencoding,Objective C,Nsstringencoding,我正在使用Objective-C应用程序,具体来说,我正在使用以下代码收集NSUserDefaults的字典表示: NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSDictionary *userDefaultsDict = [defaults dictionaryRepresentation]; 在枚举结果dict的键和对象时,有时我会发现一种不透明字符串,如下图所示: 所以这似乎是一个编码问题 如果
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *userDefaultsDict = [defaults dictionaryRepresentation];
在枚举结果dict的键和对象时,有时我会发现一种不透明字符串,如下图所示:
所以这似乎是一个编码问题
如果我尝试打印字符串的描述,调试器将正确打印:
Printing description of obj:
tsuqsx
但是,如果我尝试将obj写入文件,或以任何其他方式使用它,我会得到如下不可读的输出:
我希望达到以下目标:
- (BOOL)isProblematicString:(NSString *)candidateString {
BOOL returnValue = YES;
if ([candidateString length] <= 2) {
return NO;
}
const char *temp = [candidateString UTF8String];
long length = temp[0];
char *dest = malloc(length + 1);
long ctr = 1;
long usefulCounter = 0;
for (ctr = 1;ctr <= length;ctr++) {
if ((ctr - 1) % 3 == 0) {
memcpy(&dest[ctr - usefulCounter - 1],&temp[ctr],1);
} else {
if (ctr != 1 && ctr < [candidateString length]) {
if (temp[ctr] < 0x10 || temp[ctr] > 0x1F) {
returnValue = NO;
}
}
usefulCounter += 1;
}
}
memset(&dest[length],0,1);
free(dest);
return returnValue;
}
- (NSString *)utf8StringFromUnknownEncodedString:(NSString*)originalUnknownString {
const char *temp = [originalUnknownString UTF8String];
long length = temp[0];
char *dest = malloc(length + 1);
long ctr = 1;
long usefulCounter = 0;
for (ctr = 1;ctr <= length;ctr++) {
if ((ctr - 1) % 3 == 0) {
memcpy(&dest[ctr - usefulCounter - 1],&temp[ctr],1);
} else {
usefulCounter += 1;
}
}
memset(&dest[length],0,1);
NSString *returnValue = [[NSString alloc] initWithUTF8String:dest];
free(dest);
return returnValue;
}
-(BOOL)isProblematicsString:(NSString*)候选测试环{
BOOL returnValue=YES;
if([candidateString length]我们所说的字符串来自/Library/Preferences/.GlobalPreferences.plist
(keycom.apple.preferences.timezone.new.selected\u city
)
NSString*city=[[NSUserDefaults standardUserDefaults]
stringForKey:@“com.apple.preferences.timezone.new.selected_city”];
NSLog(@“%@”,城市);/^Zt^^]s^]^\u^^V^ u q^]^[s\^W\^Zx\^P
我希望达到以下目标:
以某种方式检测字符串是否存在编码问题
将字符串转换为UTF8编码,以便在程序的其余部分使用它
&
在尝试了所有可能的基于数据的解决方案后,使用加密并返回
此字符串没有编码问题,像\x1a
,\x1c
,…这样的字符是有效字符。
您可以使用ASCII、UTF-8等调用dataUsingEncoding:
,但所有这些字符仍将保留
显示。它们被称为(或非打印字符)。链接的Wikipedia页面解释了这些字符是什么,以及它们是如何在ASCII、扩展ASCII和unicode中定义的
您要寻找的是一种如何从字符串中删除控制字符的方法
删除控制字符
我们可以为新方法创建一个类别:
@接口NSString(控制字符)
-(NSString*)stringByRemovingControlCharacters;
@结束
@实现NSString(控制字符)
-(NSString*)stringByRemovingControlCharacters{
//删除控制字符的TODO
回归自我;
}
@结束
在下面的所有示例中,city
变量是这样创建的
NSString*city=[[NSUserDefaults standardUserDefaults]
stringForKey:@“com.apple.preferences.timezone.new.selected_city”];
…并包含@“\x1at\x1c\x1ds\x1d\x1cu\x16\x1fq\x1d\x1bs\x17\x1ax\x10”
。还有所有
以下示例使用以下代码进行了测试:
NSString*citywhithoutcc=[city-stringByRemovingControlCharacters];
//tsuqsx
NSLog(@“%@”,无CC的城市);
//{length=6,bytes=0x747375717378}
NSLog(@“%@,[CityWithout CC dataUsingEncoding:NSUTF8StringEncoding]);
拆分并连接
一种方法是利用资源。
有一个
方法(NSString
),但它仅从开头/结尾删除这些字符,
这不是你想要的。有一个技巧你可以使用:
-(NSString*)stringByRemovingControlCharacters{
NSArray*components=[自组件由字符分隔集:NSCharacterSet.controlCharacterSet];
返回[components componentsJoinedByString:@”“];
}
它通过控制字符拆分字符串,然后将这些组件连接回来。虽然不是一种非常有效的方法,但它可以工作
重症监护病房改造
另一种方法是使用ICU变换(请参见)。
有一个
方法(NSString
),但它只接受预定义的常量。文档说明:
NSStringTransform
类型定义的常量提供了基础ICU转换功能提供的功能子集。要应用ICU用户指南中定义的ICU转换,但该转换没有相应的NSStringTransform
常量,请创建NSMutableString
和cal的实例l改为使用applyTransform:reverse:range:updatedRange:
方法
让我们更新我们的实现:
-(NSString*)stringByRemovingControlCharacters{
NSMutableString*result=[self-mutableCopy];
[结果applyTransform:@“[:Cc:[:Cf:]删除”
反面:没有
范围:NSMakeRange(0,self.length)
更新范围:nil];
返回结果;
}
[:Cc://code>表示控制字符,[:Cf://code>表示格式字符。两者都表示与前面提到的字符集相同的字符集。文档:
包含Unicode通用类别Cc和Cf中字符的字符集
迭代字符
NSCharacterSet
也提供了该方法。这里我们需要迭代字符(unichar
)并检查它是否是控制字符
让我们更新我们的实现:
-(NSString*)stringByRemovingControlCharacters{
if(self.length==0){
回归自我;
}
NSU整数长度=self.length;
unichar字符[长度];
[自获取字符:字符];
NSUInteger resultLength=0;
unichar结果[长度];
NSCharacterSet*控件
(lldb) p [city description]
(__NSCFString *) $1 = 0x0000600003f6c240 @"\x1at\x1c\x1ds\x1d\x1cu\x16\x1fq\x1d\x1bs\x17\x1ax\x10"