3

在我最新版本的 XCode (4.6.2) 中,事实证明您可以使用 C 数组类型作为 Objective-C 方法的参数类型和返回类型:

@interface Foo : NSObject
@end
@implementation Foo
+ (float[2])bar:(int[4])x { // takes an array of 4 ints, and returns an array of 2 floats
  return (float[2]){ x[0] + x[1], x[0] - x[1] };
}
@end

这是令人惊讶的,因为 C 明确不允许数组类型作为 C 函数的参数类型和返回类型(它会自动将它们视为指针类型)。这意味着 Objective-C 方法不是 C 函数的语法糖吗?

这在任何地方都有记录吗?我似乎找不到任何东西。

使用上面的代码,它似乎可以正常工作:

int qux[4] = {1, 2, 3, 4};
float *baz = [Foo bar:qux];
NSLog(@"%f %f", baz[0], baz[1]); // prints 3.000000 -1.000000

进一步调查此方法的类型信息;显然,数组类型有一种新的类型编码语法:

Method method = class_getClassMethod([Foo class], @selector(bar:));
NSLog(@"%s", method_getTypeEncoding(method)); // prints [2f]24@0:8[4i]16
NSLog(@"%s", @encode(float[2])); // prints [2f]

但是,我的 Cocoa(我使用的是 Mac OS X 10.7)似乎还不能识别这种类型的编码。以下抛出NSInvalidArgumentException,原因:+[NSMethodSignature signatureWithObjCTypes:]: unsupported return type encoding spec '[2f]'

[Foo methodSignatureForSelector:@selector(bar:)];

这是一个新的 Mac OS X 10.8 的东西还是什么?

4

1 回答 1

0

这很奇怪。也许是 C++ '11 主义?

一般来说,运行时使用的编码字符串被认为是一个实现细节,并不是真的打算用于这种目的。对于相对简单的用途,它们可以很好地工作,但对于复杂类型,事情很快就会脱轨。类似地,语言数组作为值传递参数和/或返回类型通常被避免超出隐含的数组,例如 CGRect/NSRect。

正如您所发现的,类型编码会随着时间而变化,有时系统中的解析器与编译器生成的编码不匹配。10.8 可能会也可能无法解析。

于 2013-06-03T00:27:45.773 回答