2009-06-03 4 views
27

quiero conseguir esta estructuraforma array CGPoint en Objective C

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), 
}; 

Con el fin de hacer algunos cálculos y extraer datos.

He CGPoint *lines = appDelegate.averageResponseTimePoints;

Como hacer addLines[] gama de *lines?

Respuesta

48

Las matrices en C no son realmente matrices en tiempo de ejecución, donde solo son punteros a un bloque contiguo de objetos del mismo tipo. Cuando vea items[n], eso es solo azúcar sintáctica para *(items+n).

En su ejemplo addLines[1] habría *(lines+1) y addLines[0] habría *(lines+0), que es *lines. Por lo tanto, addLines es solo lines sin la desreferencia del puntero. *lines es el primer elemento de la matriz y lines es toda la matriz.

Las matrices tienen algunas diferencias con los punteros en tiempo de compilación. Por ejemplo, sizeof(addLines) le daría el tamaño de la matriz completa.

La matriz se pierde tan pronto como pasa la matriz en algún lugar donde su tamaño puede ser variable, pero aún puede utilizar el operador de subíndice. Por ejemplo:

#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; 
} 

Esto muestra la siguiente información en mi Mac:

 
sizeof(CGPoint) = 8 
sizeof(CGPoint*) = 4 
sizeof(square) = 32 
sizeof(points) = 4 
sizeof(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} 

Aquí, square es el tamaño de cuatro CGPoint s, pero una vez enviado a la función pass_back, es sólo el tamaño de una puntero, porque eso es lo que es. Cuando el puntero vuelve (y se llama returned) todavía se puede usar como una matriz.

Tenga en cuenta el número mágico 4 en el bucle. El puntero no conoce la longitud de la matriz a la que apunta.

Las matrices no se pueden reasignar con el operador =. Si realmente tiene que rellenar addLines con los puntos de lines, se puede hacer eso con algo como lo siguiente:

memcpy(addLines, lines, sizeof(CGPoint) * numberOfPoints); 

Usted tendrá que obtener numberOfPoints de alguna parte, y addLines tendrá que ser lo suficientemente grande como para manejar los puntos. Está bien si el número de puntos es una constante, pero sería malo si el número de puntos puede variar en el tiempo de ejecución, especialmente si los puntos provienen del mundo exterior (piense en la ejecución de código arbitrario).

Cambiaría averageResponseTimePoints para devolver un NSArray en lugar de una matriz de estilo C. Tendrá que encapsular el CGPoint s en objetos, ya sea su propio objeto o NSValue s.

Aquí hay un ejemplo de cómo se podría escribir 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; 
} 

Si el código se ejecuta con Cocoa Touch, puede utilizar esto para crear el valor del punto en su lugar:

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

Para obtener el CGPoint s fuera de la matriz, puede escribir algo como esto:

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

O con Cocoa Touch:

CGPoint pt = [value CGPointValue]; 
+0

Considere la diferencia entre dos métodos: 'valueWithCGPoint:' y 'valueWithPointer:'. [Detalles aquí] (http://stackoverflow.com/a/11106539/991816) – DanSkeel

+0

"Las matrices C no son realmente matrices en tiempo de ejecución". Sí, lo son, son matrices C perfectamente válidas. Lo que quieres decir es que no son NSArrays. – northernman

+0

@northernman Lo que quiere decir es que _ "The C 'runtime" no tiene ningún concepto de una "matriz" - C las matrices son trucos de lenguaje/compilador, y solo se entienden como punteros en tiempo de ejecución. _ Así que no, en tiempo de ejecución 'no son' C arrays'_perfectly valid_, porque a este respecto, C está sin manos en el punto de ejecución. –

50

Para iOS:

Crear matriz:

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

Obtener primero objeto CGPoint:

CGPoint myPoint = [myCGPointArray[0] CGPointValue]; 
+0

¡Gracias por esto! NSValue es tan útil! – GeneCode

4

probar este

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); 

Funciona. Buena suerte.

3

Probé la respuesta de Tibidabo, y no funcionó para mí. Dijo que [myCGPointArray objectAtIndex: 0] era del tipo id, por lo que no pude llamar a CGPointValue en él. hm.

esto sin embargo funcionó:

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); 

o

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; 

lo encontré aquí: How can I add CGPoint objects to an NSArray the easy way?, publicado por Jarret Hardie.

2

resuelvo mi problema haciendo lo siguiente:


NSMutableArray *myArray = [[NSMutableArray alloc] init]; 
[myArray addObject:[NSValue valueWithCGPoint:myPoint]]; 

Gracias a michael-jensen para el solution!