3

私の最新バージョンの XCode (4.6.2) では、Objective-C メソッドのパラメーターの型と戻り値の型として 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:]: サポートされていない戻り型エンコーディング仕様 '[2f]'

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

これは新しい Mac OS X 10.8 のものですか?

4

1 に答える 1

0

それはかなり奇妙です。多分 C++ '11-ism?

一般に、ランタイムで使用されるエンコーディング文字列は実装の詳細と見なされ、実際にはそのような目的で使用されることは意図されていません。比較的単純な用途には十分に機能しますが、複雑な型の場合はすぐに軌道から外れてしまいます。同様に、値渡しの引数および/または戻り値の型としての言語配列は、一般に、たとえば CGRect/NSRect の暗黙の配列を超えて回避されます。

あなたが発見したように、型エンコーディングは時間の経過とともに変化し、システム内のパーサーとコンパイラによって生成されたエンコーディングの間に不一致が生じることがあります。10.8はそれを解析できる場合とできない場合があります。

于 2013-06-03T00:27:45.773 に答える