What's the best syntax for passing a c-style array containing NSString*
to an objective-c method? Here's what I'm currently using:
将包含NSString*的c风格数组传递给objective-c方法的最佳语法是什么?以下是我目前使用的:
- (void) f:(NSString **) a {
}
- (void) g {
NSString* a[2] = {@"something", @"else"};
[self f:a];
}
3 个解决方案
#1
1
The best way would be to use an NSArray instead of a c-style array.
最好的方法是使用NSArray而不是c样式的数组。
#2
6
Your only other option is the following:
你唯一的选择是:
- (void) f:(NSString* []) a {
}
It's identical when compiled. I don't know about "best", but I prefer this version's readability. It's easier to infer that the pointer you're passing is intended to be used as an array. Pointers to pointers have different uses elsewhere (see the various NSError**
parameters used in the iOS SDK), so the distinction is helpful.
编译时是相同的。我不知道“最好”,但我更喜欢这个版本的可读性。更容易推断您传递的指针是用作数组的。指向指针的指针在其他地方有不同的用途(请参阅iOS SDK中使用的各种NSError*参数),因此这种区别很有帮助。
#3
2
Slightly better is:
稍微更好的是:
- (void) f:(NSString *[]) a
as it makes it clear it is expecting an array (passed by reference) of references to NString, rather than a reference to a reference to an NString.
很明显,它期望一个数组(通过引用传递)对NString的引用,而不是对NString的引用的引用。
However this will in all probability not change the compiler's type checking, you could pass an NSString **
without issue. The same goes if you add a bounds:
然而,这很可能不会改变编译器的类型检查,您可以毫无问题地传递一个NSString **。同样的,如果你加上一个界限:
- (void) f:(NSString *[2]) a
Here the compiler will in all probability just ignore the 2 - both when calling and inside the body, you're just adding a "comment". (If you are passing multi-dimensional arrays you do need to specify all but the last index.)
在这里,编译器很可能会忽略2——在调用时和在主体内部,您只是添加了一个“注释”。(如果要传递多维数组,则需要指定除最后一个索引之外的所有数组。)
Addendum
齿顶高
Prompted by Mike Keskinov (see comments)
由Mike Keskinov(见注释)提示
Update for ARC
更新弧
Under ARC the declaration in the question:
在《ARC》下的声明:
NSString* a[2] = {@"something", @"else"};
which has no explicit ownership qualifier is treated as:
没有显式所有权限定符被视为:
NSString* __strong a[2] = {@"something", @"else"};
that is an array of strong references to strings. When a pointer to a variable itself is passed, in this case a pointer to an array, the compiler needs to know the ownership qualification of the pointed-at variable. At the time of writing in the case of pointer to an array the compiler has no default so the declaration in this answer above:
这是对字符串的强引用的数组。当传递一个指向变量本身的指针时(在本例中是指向数组的指针),编译器需要知道指向变量的所有权限定。在编写指向数组的指针时,编译器没有默认值,因此上面这个答案中的声明是:
- (void) f:(NSString *[]) a
will produce the error, as reported by Mike Keskinov in the comments below, and you must insert an explicit ownership qualifier:
将产生错误,正如Mike Keskinov在下面的评论中所报告的,并且您必须插入一个明确的所有权限定符:
- (void) f:(NSString * __strong []) a
With that information the compiler knows how to automatically handle the string references in the array – in the body of f
the compiler will automatically as required retain and release NSString
references.
有了这些信息,编译器就知道如何自动处理数组中的字符串引用——在f的主体中,编译器会自动按照要求保留和释放NSString引用。
For more details on ARC and pointers to variables/pointers see Handling Pointer-to-Pointer Ownership Issues in ARC and NSError and __autoreleasing.
有关ARC和指向变量/指针的指针的详细信息,请参阅处理ARC和NSError以及__autoreleation中的指针对指针所有权问题。
Use For Constant Arrays
用于常量数组
Though not part of the original question is it clear that many are using C arrays as a means of having an array of string constants in Objective-C. For this particular use observe:
尽管最初的问题并不是很清楚,许多人都使用C数组作为在Objective-C中拥有字符串常量数组的手段。对于这项特殊用途,请注意:
-
If the array and parameter types are declared as arrays of constant references to strings then the array elements cannot be changed;
如果将数组和参数类型声明为字符串常量引用的数组,则不能更改数组元素;
-
Making the array static will also ensure it is only create and initialised once, even if declared with a function; and
使数组保持静态还将确保仅创建和初始化一次,即使使用函数声明;和
-
If your C array contains only string literals then the default
__strong
ownership qualifier is not required as string literals are immortal. Instead the__unsafe_unretained
qualifier may be used, the references in the array will always be valid.如果您的C数组只包含字符串文字,那么默认的__strong所有权限定符不需要作为字符串字面值。相反,可能使用__unsafe_unretain qualifier,数组中的引用将始终有效。
These produce the code fragments:
它们产生代码片段:
static NSString * const __unsafe_unretained a[2] = {@"something", @"else"};
and:
和:
- (void) f:(NSString * const __unsafe_unretained[]) a
and you have the goal of a constant array of constant NSString
literals. The compiler will not allow the array to be modified, or insert redundant memory management calls.
你有一个常量NSString常量数组的目标。编译器将不允许修改数组或插入冗余内存管理调用。
#1
1
The best way would be to use an NSArray instead of a c-style array.
最好的方法是使用NSArray而不是c样式的数组。
#2
6
Your only other option is the following:
你唯一的选择是:
- (void) f:(NSString* []) a {
}
It's identical when compiled. I don't know about "best", but I prefer this version's readability. It's easier to infer that the pointer you're passing is intended to be used as an array. Pointers to pointers have different uses elsewhere (see the various NSError**
parameters used in the iOS SDK), so the distinction is helpful.
编译时是相同的。我不知道“最好”,但我更喜欢这个版本的可读性。更容易推断您传递的指针是用作数组的。指向指针的指针在其他地方有不同的用途(请参阅iOS SDK中使用的各种NSError*参数),因此这种区别很有帮助。
#3
2
Slightly better is:
稍微更好的是:
- (void) f:(NSString *[]) a
as it makes it clear it is expecting an array (passed by reference) of references to NString, rather than a reference to a reference to an NString.
很明显,它期望一个数组(通过引用传递)对NString的引用,而不是对NString的引用的引用。
However this will in all probability not change the compiler's type checking, you could pass an NSString **
without issue. The same goes if you add a bounds:
然而,这很可能不会改变编译器的类型检查,您可以毫无问题地传递一个NSString **。同样的,如果你加上一个界限:
- (void) f:(NSString *[2]) a
Here the compiler will in all probability just ignore the 2 - both when calling and inside the body, you're just adding a "comment". (If you are passing multi-dimensional arrays you do need to specify all but the last index.)
在这里,编译器很可能会忽略2——在调用时和在主体内部,您只是添加了一个“注释”。(如果要传递多维数组,则需要指定除最后一个索引之外的所有数组。)
Addendum
齿顶高
Prompted by Mike Keskinov (see comments)
由Mike Keskinov(见注释)提示
Update for ARC
更新弧
Under ARC the declaration in the question:
在《ARC》下的声明:
NSString* a[2] = {@"something", @"else"};
which has no explicit ownership qualifier is treated as:
没有显式所有权限定符被视为:
NSString* __strong a[2] = {@"something", @"else"};
that is an array of strong references to strings. When a pointer to a variable itself is passed, in this case a pointer to an array, the compiler needs to know the ownership qualification of the pointed-at variable. At the time of writing in the case of pointer to an array the compiler has no default so the declaration in this answer above:
这是对字符串的强引用的数组。当传递一个指向变量本身的指针时(在本例中是指向数组的指针),编译器需要知道指向变量的所有权限定。在编写指向数组的指针时,编译器没有默认值,因此上面这个答案中的声明是:
- (void) f:(NSString *[]) a
will produce the error, as reported by Mike Keskinov in the comments below, and you must insert an explicit ownership qualifier:
将产生错误,正如Mike Keskinov在下面的评论中所报告的,并且您必须插入一个明确的所有权限定符:
- (void) f:(NSString * __strong []) a
With that information the compiler knows how to automatically handle the string references in the array – in the body of f
the compiler will automatically as required retain and release NSString
references.
有了这些信息,编译器就知道如何自动处理数组中的字符串引用——在f的主体中,编译器会自动按照要求保留和释放NSString引用。
For more details on ARC and pointers to variables/pointers see Handling Pointer-to-Pointer Ownership Issues in ARC and NSError and __autoreleasing.
有关ARC和指向变量/指针的指针的详细信息,请参阅处理ARC和NSError以及__autoreleation中的指针对指针所有权问题。
Use For Constant Arrays
用于常量数组
Though not part of the original question is it clear that many are using C arrays as a means of having an array of string constants in Objective-C. For this particular use observe:
尽管最初的问题并不是很清楚,许多人都使用C数组作为在Objective-C中拥有字符串常量数组的手段。对于这项特殊用途,请注意:
-
If the array and parameter types are declared as arrays of constant references to strings then the array elements cannot be changed;
如果将数组和参数类型声明为字符串常量引用的数组,则不能更改数组元素;
-
Making the array static will also ensure it is only create and initialised once, even if declared with a function; and
使数组保持静态还将确保仅创建和初始化一次,即使使用函数声明;和
-
If your C array contains only string literals then the default
__strong
ownership qualifier is not required as string literals are immortal. Instead the__unsafe_unretained
qualifier may be used, the references in the array will always be valid.如果您的C数组只包含字符串文字,那么默认的__strong所有权限定符不需要作为字符串字面值。相反,可能使用__unsafe_unretain qualifier,数组中的引用将始终有效。
These produce the code fragments:
它们产生代码片段:
static NSString * const __unsafe_unretained a[2] = {@"something", @"else"};
and:
和:
- (void) f:(NSString * const __unsafe_unretained[]) a
and you have the goal of a constant array of constant NSString
literals. The compiler will not allow the array to be modified, or insert redundant memory management calls.
你有一个常量NSString常量数组的目标。编译器将不允许修改数组或插入冗余内存管理调用。