何かの配列を返したい場合があります。呼び出し元が配列を作成し、メソッドで配列を変更できるようにする必要があることはわかっています。しかし、これはうまくいくことがわかりましたか?
@interface Test : NSObject
@end
@implementation Test
- (CGPoint[2])test {
CGPoint p1 = {1, 2};
CGPoint p2 = {3, 4};
return (CGPoint[2]) {p1, p2};
}
- (int[2])test2 {
int i = 1;
int i2 = 2;
return (int[2]){i, i2};
}
- (int[5])test3 {
int i = 1;
int i2 = 2;
return (int[5]){i, i2, 3, 4, 5};
}
@end
@implementation testTests
- (void)testExample
{
Test *t = [Test new];
CGPoint p = [t test][0];
CGPoint p2 = [t test][1];
CGPoint *ps = [t test];
CGPoint p3 = ps[0];
CGPoint p4 = ps[1];
NSLog(@"%@ %@ %@ %@", NSStringFromCGPoint(p), NSStringFromCGPoint(p2), NSStringFromCGPoint(p3), NSStringFromCGPoint(p4));
// {1, 2} {3, 4} {1, 2} {3, 4}
{
Method m = class_getInstanceMethod([Test class], @selector(test));
const char *rettype = method_copyReturnType(m);
NSUInteger size = 0;
NSGetSizeAndAlignment(rettype, &size, NULL);
NSLog(@"%s %d", rettype, size); // [2{CGPoint=ff}] 16
}
{
Method m = class_getInstanceMethod([Test class], @selector(test2));
const char *rettype = method_copyReturnType(m);
NSUInteger size = 0;
NSGetSizeAndAlignment(rettype, &size, NULL);
NSLog(@"%s %d", rettype, size); // [2i] 8
}
{
Method m = class_getInstanceMethod([Test class], @selector(test3));
const char *rettype = method_copyReturnType(m);
NSUInteger size = 0;
NSGetSizeAndAlignment(rettype, &size, NULL);
NSLog(@"%s %d", rettype, size); // [5i] 20
}
}
@end
したがって、構造体を返すのと同じように、何かの配列を直接返すことができるようです。示唆されているようNSGetSizeAndAlignment
に、戻り値は実際には単なるポインタではなく配列全体です。( の場合は 16、 のCGPoint[2]
場合は 8、 のint[2]
場合は 20 int[5]
)
しかし、実際に返された値を使用するには、これしかできません
CGPoint *ps = [t test];
これps
は単なるポインタです。問題は、このような配列を安全に返すことができるかということです。配列はどこに割り当てられますか? 呼び出し先関数のスタック内または呼び出し元関数のスタック内? 配列全体が呼び出し先関数からコピーされるか、コンパイラーが呼び出し元関数で配列を自動的に割り当てた構造体のようにコピーされるのは本当ですか?
Xcode 4.6.2 を使用しています
アップデート
これは、iOS アプリ (ARM)、iOS シミュレーター (x86)、および 32 ビット OSX アプリを含む 32 ビット アプリでのみ動作するようです。