【问题标题】:Objective-c syntax for passing a c-style array of NSStrings用于传递 NSStrings 的 c 样式数组的 Objective-c 语法
【发布时间】:2012-05-19 09:51:05
【问题描述】:

将包含NSString* 的c 样式数组传递给objective-c 方法的最佳语法是什么?这是我目前使用的:

- (void) f:(NSString **) a {

}

- (void) g {
    NSString* a[2] = {@"something", @"else"};
    [self f:a];
}

【问题讨论】:

  • 不要。使用 Cocoa 中的 Cocoa 集合或非 Objective-C 对象与“本机”C/C++ 进行互操作。
  • 戴夫的答案是正确的;其他答案在技术上可能是正确的,但这并不能使它成为正确的解决方案。现在,当然,你认为你需要一个 C 数组可能有一些深奥的原因,但它可能是不太理想的使用模式......(有原因,但它们主要归结为“我们有一个蹩脚的库我们无法控制并且必须以某种方式使用它”)
  • 由于 Objective-C 没有提供任何“正常”的方式来声明常量数组(请参阅此处的讨论:stackoverflow.com/questions/2436463/…),我认为这是一个有效的问题,并且在您需要时是正确的方法传递常量数组。

标签: objective-c arrays syntax methods parameter-passing


【解决方案1】:

最好的方法是使用 NSArray 而不是 c 样式的数组。

【讨论】:

  • 请善待试图提供帮助的人
  • @PhilippeLeybaert 我确实同意。虽然我很欣赏NSArray 的建议,但在我使用 c 样式数组的那一刻,我肯定会在其他情况下使用该对象。
  • @SundayMonday 你的“此刻”无法承受,@Dave Wood 的回答是正确的。 非常没有理由使用Objective-C ids 的数组。这样做会使 Cocoa 中的所有标准(手动或 ARC)内存管理无效,从长远来看肯定会咬你一口。如果重点是 C/C++ 互操作,还有更好的方法。
  • 我同意这里的观点:这是正确的做法,如果在技术上不是问题的答案。
【解决方案2】:

您唯一的其他选择如下:

- (void) f:(NSString* []) a {

}

编译时是一样的。我不知道“最好”,但我更喜欢这个版本的可读性。更容易推断出您传递的指针旨在用作数组。指向指针的指针在其他地方有不同的用途(参见 iOS SDK 中使用的各种 NSError** 参数),因此区分是有帮助的。

【讨论】:

  • 谢谢。正在寻找这个并且您正确回答了 OP 问题。
【解决方案3】:

稍微好一点的是:

- (void) f:(NSString *[]) a

因为它清楚地表明它需要一个对 NString 的引用的数组(通过引用传递),而不是对 NString 的引用的引用。

但是这很可能不会更改编译器的类型检查,您可以毫无问题地传递NSString **。如果添加边界也是如此:

- (void) f:(NSString *[2]) a

在这里,编译器很可能会忽略 2 - 无论是在调用时还是在正文中,您都只是添加了一个“注释”。 (如果您传递的是多维数组,则需要指定除最后一个索引之外的所有索引。)

附录

由 Mike Keskinov 提示(参见 cmets)

ARC 更新

在 ARC 下问题中的声明:

NSString* a[2] = {@"something", @"else"};

没有明确的所有权限定符被视为:

NSString* __strong a[2] = {@"something", @"else"};

这是一个对字符串的强引用数组。当传递指向变量本身的指针时,在这种情况下是指向数组的指针,编译器需要知道指向变量的所有权资格。在编写指向数组的指针的情况下,编译器没有默认值,因此上述答案中的声明:

- (void) f:(NSString *[]) a

将产生错误,正如 Mike Keskinov 在下面的 cmets 中所报告的,您必须插入一个明确的所有权限定符:

- (void) f:(NSString * __strong []) a

有了这些信息,编译器就知道如何自动处理数组中的字符串引用——在f 的主体中,编译器将根据需要自动保留和释放NSString 引用。

有关 ARC 和指向变量/指针的指针的更多详细信息,请参阅 Handling Pointer-to-Pointer Ownership Issues in ARCNSError and __autoreleasing

用于常量数组

虽然不是原始问题的一部分,但很明显,许多人使用 C 数组作为在 Objective-C 中拥有字符串数组的一种方式。constants。对于这种特殊用途,请注意:

  1. 如果数组和参数类型声明为对字符串的常量引用数组,则数组元素不能更改;

  2. 将数组设为静态还可以确保它只创建和初始化一次,即使使用函数声明也是如此;和

  3. 如果您的 C 数组仅包含字符串文字,则不需要默认的 __strong 所有权限定符,因为字符串文字是不朽的。相反,可以使用 __unsafe_unretained 限定符,数组中的引用将始终有效。

这些会产生代码片段:

static NSString * const __unsafe_unretained a[2] = {@"something", @"else"}; 

和:

- (void) f:(NSString * const __unsafe_unretained[]) a

并且您的目标是常量NSString 文字的常量数组。编译器将不允许修改数组,或插入多余的内存管理调用。

【讨论】:

  • 这给了我编译器错误,告诉我我需要“指定传递数组的所有权”。不知道这意味着什么,但我简单地切换到 ** 方法,它工作得很好。
  • @MikeKeskinov - 这是由于 ARC。从这个评论和你对问题本身的评论看来,你正在寻求创建一个常量字符串的常量数组。请参阅答案的附录。 HTH
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多