4

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

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

}

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

3 回答 3

6

您唯一的其他选择如下:

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

}

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

于 2012-05-10T19:22:33.963 回答
2

稍微好一点的是:

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

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

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

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

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

附录

由 Mike Keskinov 提示(见评论)

ARC 更新

在 ARC 下,问题中的声明:

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

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

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

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

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

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

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

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

有关 ARC 和指向变量/指针的指针的更多详细信息,请参阅处理 ARC和NSError 和 __autoreleasing中的指针对指针所有权问题

用于常量数组

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

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

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

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

这些产生代码片段:

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

和:

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

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

于 2012-05-10T19:23:36.287 回答
0

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

于 2012-05-10T19:04:27.320 回答