- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我今天陷入了愚蠢的困境,因为我无法将一段简单的 ObjC 代码转换为其 Cpp 等效代码。我有这个:
const UInt8 *myBuffer = [(NSString*)aRequest UTF8String];
const UInt8 *myBuffer = (const UInt8 *)CFStringGetCStringPtr(aRequest, kCFStringEncodingUTF8);
最佳答案
这是 Cocoa 在幕后完成所有杂乱工作的事情之一,在您不得不卷起袖子自己动手之前,您永远不会真正意识到事情的复杂性。
为什么它不“简单”的简单答案是因为 NSString
(和 CFString
)处理处理多个字符集、Unicode 等的所有复杂细节,同时提供用于操作字符串的简单、统一的 API。它是最好的面向对象-“如何”的细节(NS|CF)String
处理具有不同字符串编码(UTF8、MacRoman、UTF16、ISO 2022 日语等)的字符串是一个私有(private)实现细节。这一切都“有效”。
它有助于了解如何[@"..." UTF8String]
作品。这是一个私有(private)的实现细节,所以这不是福音,而是基于观察到的行为。当你发送一个字符串 UTF8String
消息,字符串做一些近似的事情(没有实际测试,所以把它当作伪代码,实际上有更简单的方法来做完全相同的事情,所以这过于冗长):
- (const char *)UTF8String
{
NSUInteger utf8Length = [self lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
NSMutableData *utf8Data = [NSMutableData dataWithLength:utf8Length + 1UL];
char *utf8Bytes = [utf8Data mutableBytes];
[self getBytes:utf8Bytes
maxLength:utf8Length
usedLength:NULL
encoding:NSUTF8StringEncoding
options:0UL
range:NSMakeRange(0UL, [self length])
remainingRange:NULL];
return(utf8Bytes);
}
-UTF8String
返回是因为
NSMutableData
是自动发布的。
-UTF8String
方法调用现在要复杂得多。
NSString
实际上是在/与 CoreFoundation/
CFString
中实现的,所以显然有一条来自
CFStringRef
的路径->
-UTF8String
.它只是不像
NSString
那样整洁和简单的
-UTF8String
.大多数复杂情况与内存管理有关。以下是我过去处理它的方法:
void someFunction(void) {
CFStringRef cfString; // Assumes 'cfString' points to a (NS|CF)String.
const char *useUTF8StringPtr = NULL;
UInt8 *freeUTF8StringPtr = NULL;
CFIndex stringLength = CFStringGetLength(cfString), usedBytes = 0L;
if((useUTF8StringPtr = CFStringGetCStringPtr(cfString, kCFStringEncodingUTF8)) == NULL) {
if((freeUTF8StringPtr = malloc(stringLength + 1L)) != NULL) {
CFStringGetBytes(cfString, CFRangeMake(0L, stringLength), kCFStringEncodingUTF8, '?', false, freeUTF8StringPtr, stringLength, &usedBytes);
freeUTF8StringPtr[usedBytes] = 0;
useUTF8StringPtr = (const char *)freeUTF8StringPtr;
}
}
long utf8Length = (long)((freeUTF8StringPtr != NULL) ? usedBytes : stringLength);
if(useUTF8StringPtr != NULL) {
// useUTF8StringPtr points to a NULL terminated UTF8 encoded string.
// utf8Length contains the length of the UTF8 string.
// ... do something with useUTF8StringPtr ...
}
if(freeUTF8StringPtr != NULL) { free(freeUTF8StringPtr); freeUTF8StringPtr = NULL; }
}
CFString
用于存储字符串的内容。如
CFString
如果字符串内容以 UTF8(或适当兼容的编码,例如 ASCII)编码,则很可能是
CFStringGetCStringPtr()
将返回非
NULL
.这显然是最好、最快的情况。如果由于某种原因无法获得该指针,请说 if
CFString
将其内容编码为 UTF16,然后分配一个缓冲区为
malloc()
当它被转码为 UTF8 时,它足够大以包含整个字符串。然后,在函数结束时,它会检查是否分配了内存和
free()
有必要的话。
CFString
“倾向于”(这是一个私有(private)实现细节,因此它可以并且确实会在不同版本之间发生变化)将“简单”字符串编码为 MacRoman,这是一种 8 位宽编码。 MacRoman 与 UTF8 一样,是 ASCII 的超集,因此所有 < 128 的字符都等同于它们的 ASCII 对应字符(或者,换句话说,任何 < 128 的字符都是 ASCII)。在 MacRoman 中,>= 128 的字符是“特殊”字符。它们都有 Unicode 等价物,并且往往是额外的货币符号和“扩展的西方”字符之类的东西。见
Wikipedia - MacRoman了解更多信息。但仅仅因为一个
CFString
说它是 MacRoman(
CFString
kCFStringEncodingMacRoman
的编码值,
NSString
NSMacOSRomanStringEncoding
的编码值)并不意味着它有字符 >= 128 。如果
kCFStringEncodingMacRoman
CFStringGetCStringPtr()
返回的编码字符串完全由 < 128 个字符组成,那么它完全等同于其 ASCII (
kCFStringEncodingASCII
) 编码表示,也完全等同于字符串 UTF8 (
kCFStringEncodingUTF8
) 编码表示。
kCFStringEncodingMacRoman
来“过关”。而不是
kCFStringEncodingUTF8
打电话时
CFStringGetCStringPtr()
.如果您的字符串需要严格的 UTF8 编码,但使用
kCFStringEncodingMacRoman
,事情“可能”(可能)会更快,然后检查以确保
CFStringGetCStringPtr(string, kCFStringEncodingMacRoman)
返回的字符串只包含 < 128 的字符。如果字符串中有 >= 128 的字符,则通过
malloc()
走慢速路线一个缓冲区来保存转换后的结果。例子:
CFIndex stringLength = CFStringGetLength(cfString), usedBytes = 0L;
useUTF8StringPtr = CFStringGetCStringPtr(cfString, kCFStringEncodingUTF8);
for(CFIndex idx = 0L; (useUTF8String != NULL) && (useUTF8String[idx] != 0); idx++) {
if(useUTF8String[idx] >= 128) { useUTF8String = NULL; }
}
if((useUTF8String == NULL) && ((freeUTF8StringPtr = malloc(stringLength + 1L)) != NULL)) {
CFStringGetBytes(cfString, CFRangeMake(0L, stringLength), kCFStringEncodingUTF8, '?', false, freeUTF8StringPtr, stringLength, &usedBytes);
freeUTF8StringPtr[usedBytes] = 0;
useUTF8StringPtr = (const char *)freeUTF8StringPtr;
}
关于iphone - NSString 的 UTF8String 的 CFString Equiv 是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1609565/
如何编译它? 在此函数的第二行: func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWi
我使用此代码获取 ABPerson 的姓氏 CFStringRef lastNameRef = ABRecordCopyValue((ABRecordRef)personRecordRef, kABP
我想在子函数中为 CFString 分配空间。像这样: void fun(CFStringRef *ref) { ref = CFStringCreateWithCString(NULL, "
我正在为 iPhone 开发应用程序,遇到了一些内存管理问题。在应用程序执行期间,事件字节数不断增加而不受限制。我试图在我的代码中找出问题,但似乎找不到任何会导致事件字节数急剧增加的东西。我在执行过程
不知何故,下面的代码使我的应用程序崩溃: NSString *filename = [NSString stringWithFormat:@"%@%@", dbPath, @"BAR"]; NSStr
我正在开发的一个应用程序在 iPhone 上运行时不断崩溃,但在模拟器上却没有(尽管在没有符号 malloc_error_break 的情况下运行时会显示警告,但该应用程序在 Sim 上仍然运行) 我
我想知道一个字符串是否是单字节编码。 CFShowStr 可以完成这项工作,但它将消息输出到控制台。 CFShowStr 函数输出消息如下所示,IsEightBit 项就是我想要的: Length 7
我有一个CFMutableDictionaryRef ,调试器中的部分内容是: "device-id" = ; model = ; "vendor-id" = ; 现在我可以获得 key model
我正在应用程序上运行仪器。根据仪器,未检测到任何泄漏。 但是,类别CFString (store) 一直在上升。有谁知道 CFString (store) 是什么? 这是否意味着我有泄漏? 最佳答案
我看过问答 here about the self keyword in Swift . 但是,对我来说,这并不能解释在 this question 的以下代码片段中使用 .self let attr
我有以下代码将 String 转换为 CFString 和 backwarts: string path = @"C:\Users\ayi\Desktop\Failed\AngryBirds.ipa"
在 xcode 中使用内存图调试器时,我看到了一些内存泄漏。 Backtrace 没有直接链接到我的任何代码,而是通过跟踪猜测它的保存以假设它与组合和一些 DataTaskPublisher 相关。
首先,这与古代技术有关。我正在处理的程序端口在 Metrowerks Codewarrior 9 中维护,目标是 PPC。 用于 MSL C 的 FSRefParentAndFilename_fope
这个问题在这里已经有了答案: NSString is exactly the same as CFString? (1 个回答) 关闭 9 年前。 我没有理解 iOS 中 CFString 和 NS
我很快就开始使用 Cocoa 编程 Mac OS X 应用程序,所以这确实是一个新问题。为此事道歉。 首先我的代码片段: - (id)tableView:(NSTableView *)tableVie
自 Swift 2 起,可以从 Swift 调用采用 C 回调的 C 函数,而无需中间包装器。 许多 C 事件处理 API 都遵循首先创建上下文的模式: struct Context { CF
我正在尝试掌握在 Mac OS X 中使用 JNA 的窍门。我想访问 Carbon 库,但 Cocoa 没有对应的库,因此 Rococoa 无法帮助我(我认为...) 当我尝试调用需要 CFStrin
我有一个返回 CFString 的库,我试图在 C# 中获取该字符串值。问题是我不知道如何在 C# 中执行此操作。 使外部函数返回 CFString 将不起作用,因为它会引发异常“传递给非托管代码的类
我正在解决我的 iPad 应用程序中的一些内存分配问题,并且花了很长时间观察 CFString 在zombies instrument,直到我切换到 Leaks or allocations inst
我最近更新到 Xcode 6.1 以便能够与 iOS 8.1 一起工作,但现在我的最新项目面临错误。 对于以下行,我收到错误消息“CFString!不符合协议(protocol) Hashable”:
我是一名优秀的程序员,十分优秀!