如何在Objective-C中形成CGPoint数组?

30
我想获得这个结构:
CGPoint addLines1[] =
{
    CGPointMake(30.0, 150.0),
    CGPointMake(41.67, 145.19),
    CGPointMake(53.33, 103.25),
    CGPointMake(65.0, 131.67),
    CGPointMake(76.67, 106.11),
    CGPointMake(88.33, 110.20),
    CGPointMake(100.0, 111.54),
    CGPointMake(111.67, 112.13),
    CGPointMake(123.33, 115.66),
    CGPointMake(135.0, 123.7),
    CGPointMake(146.67, 125.53),
    CGPointMake(158.33, 115.1),
    CGPointMake(170.0, 69.38),
    CGPointMake(181.67, 112.47),
    CGPointMake(193.33, 65.1),
    CGPointMake(205.0, 103.33),
    CGPointMake(216.67, 92.6),
    CGPointMake(228.33, 54.76),
    CGPointMake(240.0, 79.66),
    CGPointMake(251.67, 53.81),
    CGPointMake(263.33, 56.81),
    CGPointMake(275.0, 88.19),
    CGPointMake(286.67, 74.81),
    CGPointMake(298.33, 28.1),
    CGPointMake(310, 20.0),
};

为了进行一些计算并绘制数据。

我有 CGPoint *lines = appDelegate.averageResponseTimePoints;

如何从*lines创建数组addLines[]

5个回答

52

对于iOS:

创建数组:

NSArray *myCGPointArray = @[[NSValue valueWithCGPoint:CGPointMake(30.0, 150.0)],[NSValue valueWithCGPoint:CGPointMake(41.67, 145.19)]];

获取第一个CGPoint对象:

CGPoint myPoint = [myCGPointArray[0] CGPointValue];

谢谢!NSValue非常有用! - GeneCode

50

C语言中的数组在运行时实际上不是真正的数组,它们只是指向相同类型对象的连续块的指针。当你看到items[n]时,这只是*(items+n)的语法糖。

在你的例子中,addLines[1]将是*(lines+1),而addLines[0]将是*(lines+0),即*lines。因此,addLines就是没有指针解引用的lines*lines是数组中的第一个项,而lines则是整个数组。

数组与指针在编译时有一些区别。例如,sizeof(addLines)会给出整个数组的大小。

一旦你将数组传递到可能具有可变大小的位置,数组的数组性质就会丢失,但你仍然可以使用下标运算符。例如:

#include <Foundation/Foundation.h>

#define showsize( expr ) ( printf(#expr " = %zd\n", ( expr ) ) )

CGPoint *
pass_back(CGPoint points[4])
{
    showsize(sizeof(points));
    return points;
}

int
main(void)
{
    CGPoint square[] = {CGPointMake(-1.0,  1.0),
                        CGPointMake( 1.0,  1.0),
                        CGPointMake( 1.0, -1.0),
                        CGPointMake(-1.0, -1.0)};
    CGPoint* returned;
    int i;

    showsize(sizeof(CGPoint));
    showsize(sizeof(CGPoint*));
    showsize(sizeof(square));
    returned = pass_back(square);
    showsize(sizeof(returned));

    for (i = 0; i < 4; ++i) {
        printf("returned[%d] = {%0.1f, %0.1f}\n", i, (float) returned[i].x,
                                                 (float) returned[i].y);
    }

    return 0;
}
这在我的 Mac 上输出如下:
CGPoint 的大小为 8
CGPoint* 的大小为 4
square 的大小为 32
points 的大小为 4
returned 的大小为 4
returned[0] = {-1.0, 1.0}
returned[1] = {1.0, 1.0}
returned[2] = {1.0, -1.0}
returned[3] = {-1.0, -1.0}
这里,`square` 是四个 `CGPoint` 的大小,但一旦发送到 `pass_back` 函数,它只是一个指针的大小,因为它就是一个指针。当指针(命名为 `returned`)返回时,仍然可以像数组一样使用。
请注意循环中的魔法数字 `4`。指针不知道它所指向的数组的长度。
数组不能使用 `=` 运算符重新分配。如果你真的必须使用 `lines` 中的点填充 `addLines`,可以使用以下代码:
memcpy(addLines, lines, sizeof(CGPoint) * numberOfPoints);
你需要从某个地方获取“numberOfPoints”,并且“addLines”必须足够大,以处理这些点。如果点的数量是常量,那就没问题,但如果点的数量在运行时可以变化,特别是如果这些点来自外部世界(考虑任意代码执行),那就会很糟糕。
我会将“averageResponseTimePoints”更改为返回NSArray而不是C风格的数组。您需要将CGPoint封装在对象中-可以是您自己的对象或NSValues。以下是如何编写“averageResponseTimePoints”的示例:
- (NSArray*) averageResponseTimePoints
{
    NSMutableArray* result = [[[NSMutableArray alloc] init] autorelease];

    for (int i = 0; i < numberOfPoints; ++i) {
        NSValue* point = [NSValue value:points+i
                           withObjCType:@encode(CGPoint)];
        [result addObject:point];
    }

    return result;
}

如果你的代码运行在CocoaTouch上,你可以使用以下方法创建这个点的值:

NSValue* point = [NSValue valueWithCGPoint:points[i]];

要从数组中获取CGPoint,可以编写类似以下内容的代码:

for (NSValue* value in result) {
    NSPoint pt;
    [value getValue:&pt];
    NSLog(@"%f %f", pt.x, pt.y);
}

或者使用CocoaTouch:

CGPoint pt = [value CGPointValue];

考虑两种方法之间的区别:valueWithCGPoint:valueWithPointer:详见此处 - DanSkeel
"C 数组在运行时并不是真正的数组"。不,它们是完全有效的 C 数组。你的意思是它们不是 NSArray。 - northernman
@northernman,Will 的意思是:“C 'runtime' 没有 'array' 的概念—— C 数组只是语言/编译器级别的技巧,在运行时只能理解为指针。” 因此,在运行时它们不是“完全有效的 C 数组”,因为在这方面,C 在运行时是不干涉的。 - Slipp D. Thompson
@northernman 相对于那些具有数组运行时表示的语言,这种区别更加明显——例如 Objective-C 的 NSArray、C++ 的 STL array/deque/list 等,Java 中遵循 isArray() 的类型,C# 中遵循 IsArray 的类型,JavaScript 的 Array 等。 - Slipp D. Thompson
你正在应用“现代”数组的定义。我将采用C语言发明者之一的术语作为权威:http://www.lysator.liu.se/c/bwk-tutor.html#array - northernman

4

试试这个

CGPoint A[10];
A[0] = CGPointMake(10.0, 10.0);
A[1] = CGPointMake(10.0, 12.0);
float x = A[1].y;
NSLog(@"%.0f", x);

它可以工作。祝你好运。


3
我尝试了Tibidabo的答案,但对我无效。它说[myCGPointArray objectAtIndex:0]是id类型,所以我无法调用CGPointValue。嗯。
然而,这个方法有效:
NSArray *points = [NSArray arrayWithObjects:
                   [NSValue valueWithCGPoint:CGPointMake(5.5, 6.6)],
                   [NSValue valueWithCGPoint:CGPointMake(7.7, 8.8)],
                   nil];

NSValue *val = [points objectAtIndex:0];
CGPoint point = [val CGPointValue];
float X = point.x;
NSLog(@"cgpoint value is: %f", X);

或者

NSArray *points = [NSArray arrayWithObjects:
                        [NSValue valueWithCGPoint:CGPointMake(20, 6.6)],
                        [NSValue valueWithCGPoint:CGPointMake(7.7, 8.8)],
                        nil];
float xCoordinate = [[points objectAtIndex:0] CGPointValue].x;

我在这里找到了它:如何简单地将CGPoint对象添加到NSArray中?,作者是Jarret Hardie。


2
我解决了我的问题,做了以下操作:
NSMutableArray *myArray = [[NSMutableArray alloc] init];
[myArray addObject:[NSValue valueWithCGPoint:myPoint]];

感谢michael-jensen提供的解决方案

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接