【问题标题】:Unfamiliar C syntax in Objective-C contextObjective-C 上下文中不熟悉的 C 语法
【发布时间】:2009-06-30 20:23:59
【问题描述】:

我从 C# 来到 Objective-C,没有任何 C 中级知识。(是的,是的,我需要在某个时候学习 C,我完全打算这样做。)在 Apple 的 Certificate, Key, and Trust Services Programming Guide 中,有以下内容代码:

static const UInt8 publicKeyIdentifier[] = "com.apple.sample.publickey\0";
static const UInt8 privateKeyIdentifier[] = "com.apple.sample.privatekey\0";

我有一个NSString,我想在这里用作标识符,而在我的一生中,我无法弄清楚如何将它放入这个数据结构中。通过谷歌搜索也没有结果。我查看了NSString Class Reference 并查看了UTF8StringgetCharacters 方法,但我无法将产品放入结构中。

我缺少什么简单易行的技巧?

【问题讨论】:

    标签: objective-c cocoa string nsstring constants


    【解决方案1】:

    这些是 C 字符串:字符数组(不是 NSArray,而是 C 数组)。最后一个字符是 NUL,数值为 0。

    “UInt8”是无符号八位字节的 CoreServices 名称,(在 Mac OS X 上)与无符号字符相同。

    static 表示该数组特定于该文件(如果它在文件范围内)或在函数调用中持续存在(如果它在方法或函数体中)。

    const 的意思正是您所猜测的:您无法更改这些数组中的字符。

    \0 是 NUL,但如这些示例中所示,将其显式包含在 "" 文字中是多余的。 "" 文字(没有 @)无论如何都是 NUL 终止的。

    C 没有指定编码。在 Mac OS X 上,它通常与 ASCII 兼容,通常是 UTF-8。

    要将 NSString 转换为 C 字符串,请使用 UTF8StringcStringUsingEncoding:。要让 NSString 将 C 字符串提取到缓冲区中,请使用 getCString:maxLength:encoding:

    【讨论】:

    • 当,我只能标记一个作为答案。 Jason Coco 涵盖了“简单的技巧”部分,但您确实在“不熟悉的语法”问题上提供了帮助。非常感谢!
    【解决方案2】:

    我认为有些人在这里忽略了重点。大家已经解释了为标签设置的两个常量数组,但是如果你想使用NSString,你可以简单地将它添加到属性字典中。您不必将其转换为任何东西。例如:

    NSString *publicTag = @"com.apple.sample.publickey";
    NSString *privateTag = @"com.apple.sample.privatekey";
    

    示例的其余部分保持不变。在这种情况下,根本不需要 C 字符串文字。

    【讨论】:

    • 如果他能直接把它当成NSString,那肯定是真的。如果他需要与需要 char* 的其他代码交互,那么转换它仍然是正确的做法。由于 Apple 示例从字符串创建 NSData 对象,因此他还可以使用 [theString dataUsingEncoding: NSUnicodeStringEncoding] 之类的内容。
    • 这就是我在 const 完全明显的问题出现后最终要做的事情。
    • @quinn - 我认为 Apple 的示例有点令人困惑,可能有人只是从旧文档中更新示例。他们将字符串打包到 NSData 对象中的唯一原因是这样他们就可以将它们插入到新 API 期望的 CFDictionary 中。较旧的 API(在 Mac 上使用,但不在 iPhone 上使用的 API)仍然需要 C 字符串作为参数。
    【解决方案3】:

    从 NSString 获取char*(C 字符串)并不是什么棘手的部分。 (顺便说一句,我还建议使用 UTF8String,它更简单。)Apple 提供的代码之所以有效,是因为它将 C 字符串文字 分配给 static const 数组变量。将函数或方法调用的结果分配给 const 可能不起作用。

    我最近回答了一个关于 defining a constant in Objective-C 的 SO 问题,这应该对您的情况有所帮助。您可能不得不通过删除 const 修饰符来妥协。如果它被声明为static,你至少知道声明它的编译单元之外的任何人都不能引用它,所以只要确保你不要让对它的引用“逃逸”,这样其他代码就可以通过指针修改它等。

    但是,正如 @Jason 指出的那样,您甚至可能根本不需要将其转换为 char*。示例代码为每个字符串创建一个 NSData 对象。您可以在代码中执行类似的操作(替换步骤 1 和 3):

    NSData* publicTag  = [@"com.apple.sample.publickey"  dataUsingEncoding:NSUnicodeStringEncoding];
    NSData* privateTag = [@"com.apple.sample.privatekey" dataUsingEncoding:NSUnicodeStringEncoding];
    

    如果你已经有一个 NSString,那在我看来肯定比处理 C 数组更容易。

    【讨论】:

      【解决方案4】:

      试试这个

      NSString *newString = @"这是一个测试字符串。";
      char *theString;

      theString = [newString cStringWithEncoding:[NSString defaultCStringEncoding]];

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多