NSString*
将包含的 c 样式数组传递给 Objective-c 方法的最佳语法是什么?这是我目前正在使用的:
- (void) f:(NSString **) a {
}
- (void) g {
NSString* a[2] = {@"something", @"else"};
[self f:a];
}
NSString*
将包含的 c 样式数组传递给 Objective-c 方法的最佳语法是什么?这是我目前正在使用的:
- (void) f:(NSString **) a {
}
- (void) g {
NSString* a[2] = {@"something", @"else"};
[self f:a];
}
您唯一的其他选择如下:
- (void) f:(NSString* []) a {
}
编译时是一样的。我不知道“最好”,但我更喜欢这个版本的可读性。更容易推断出您传递的指针旨在用作数组。指向指针的指针在其他地方有不同的用途(参见NSError**
iOS SDK 中使用的各种参数),因此区分是有帮助的。
稍微好一点的是:
- (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 中拥有字符串常量数组的一种方式。对于这种特殊用途,请注意:
如果数组和参数类型被声明为对字符串的常量引用数组,则数组元素不能更改;
使数组静态也将确保它只创建和初始化一次,即使使用函数声明也是如此;和
如果您的 C 数组仅包含字符串文字,则__strong
不需要默认所有权限定符,因为字符串文字是不朽的。相反,__unsafe_unretained
可以使用限定符,数组中的引用将始终有效。
这些产生代码片段:
static NSString * const __unsafe_unretained a[2] = {@"something", @"else"};
和:
- (void) f:(NSString * const __unsafe_unretained[]) a
并且您的目标是常量字面量的常量数组NSString
。编译器将不允许修改数组或插入冗余内存管理调用。
最好的方法是使用 NSArray 而不是 c 样式的数组。