iphone - ¿Cómo agrego un CGPoint a NSMutableArray?
objective-c nsarray (6)
Quiero almacenar mi CGPoint en la Matriz NSMutable, así que tengo un método como este:
[self.points addObject:CGPointMake(x, y)];
Pero me salió el error, decía que:
Tipo incompatible para el argumento 1 de "addObject".
Por lo tanto, reviso la API,
- (void)addObject:(id)anObject
anObjeto El objeto a agregar al final del contenido del receptor. Este valor no debe ser nulo.
Entonces, creo que el " CGPointMake " puede hacer un objeto, pero no puede ser asignado. ¿Lo que pasa?
Desafortunadamente para usted, un CGPoint no es un objeto Objective-c. Es una estructura. Si Apple hace doble clic en CGPoint, debería saltar a la definición.
struct CGPoint {
CGFloat x;
CGFloat y;
};
typedef struct CGPoint CGPoint;
Si desea almacenar CGPoint en una NSArray, primero deberá envolverlos. Puede usar NSValue para esto o escribir su propio envoltorio.
ver Convertir un CGPoint a NSValue
EDITAR> Hay una pequeña sobrecarga para cada llamada de método de object-c, y crear y destruir objetos implica muchas llamadas de método antes de que se utilicen para cualquier cosa. No debería preocuparse por esto normalmente, pero para objetos muy pequeños que encapsulan poco comportamiento y que tienen vidas cortas, esto puede afectar el rendimiento. Si Apple usara objetos para todos los puntos, rectos, tamaños e incluso entradas, flotadores, etc., el rendimiento sería peor.
El problema es que CGPoint es en realidad solo una estructura en C, no es un objeto:
struct CGPoint {
CGFloat x;
CGFloat y;
};
typedef struct CGPoint CGPoint;
Si está en el iPhone, puede usar las adiciones NSValue UIKit para convertir el CGPoint en un objeto NSValue.
Consulte esta respuesta anterior para ver ejemplos: ¿Cómo puedo agregar objetos CGPoint a una NSArray de manera fácil?
Para aprovechar la respuesta dada por atbreuer11, puede convertir su CGPoint a NSValue, almacenarlo en NSMutableArray y convertirlo nuevamente usando lo siguiente:
//Convert CGPoint and Store it
CGPoint pointToConvert = CGPointMake(100.0f, 100.0f);
NSValue *valueToStore = [NSValue valueWithCGPoint:pointToConvert];
NSMutableArray *arrayToKeep =[NSMutableArray arrayWithObject:valueToStore];
Luego restaurarlo de nuevo:
CGPoint takeMeBack;
for (NSValue *valuetoGetBack in arrayToKeep) {
takeMeBack = [valuetoGetBack CGPointValue];
//do something with the CGPoint
}
Esa es probablemente la forma más fácil de hacerlo. Puedes escribir una clase completa y hacer todo tipo de manipulación de datos, pero creo que sería una exageración, a menos que realmente tengas que hacerlo.
También puedes hacer lo siguiente:
[myArray addObject:[NSValue valueWithCGPoint:MyCGPoint]];
Una forma sencilla de manejar CGPoint
(o cualquier otra estructura heredada que no sea NSObject
) es crear una nueva clase heredada de NSObject
.
El código es más largo, pero limpio. A continuación se muestra un ejemplo:
En el archivo .h:
@interface MyPoint:NSObject
{
CGPoint myPoint;
}
- (id) init;
- (id) Init:(CGPoint) point;
- (BOOL)isEqual:(id)anObject;
@end
En el archivo .m:
@implementation MyPoint
- (id) init
{
self = [super init];
myPoint = CGPointZero;
return self;
}
- (id) Init:(CGPoint) point{
myPoint.x = point.x;
myPoint.y = point.y;
return self;
}
- (BOOL)isEqual:(id)anObject
{
MyPoint * point = (MyPoint*) anObject;
return CGPointEqualToPoint(myPoint, point->myPoint);
}
@end
Aquí hay un ejemplo de código que muestra el uso, no se olvide de liberar !
//init the array
NSMutableArray *pPoints;
pPoints = [[NSMutableArray alloc] init];
// init a point
MyPoint *Point1 = [[MyPoint alloc]Init:CGPointMake(1, 1)];
// add the point to the array
[pPoints addObject:[[MyPoint alloc] Point1]];
//add another point
[Point1 Init:CGPointMake(10, 10)];
[pPoints addObject:[[MyPoint alloc] Point1]];
[Point1 Init:CGPointMake(3, 3)];
if ([pPoints Point1] == NO))
NSLog(@"Point (3,3) is not in the array");
[Point1 Init:CGPointMake(1, 1)];
if ([pPoints Point1] == YES))
NSLog(@"Point (1,1) is in the array");
Swift 3.x
// Convertir CGPoint a NSValue
let cgPoint = CGPoint(x: 101.4, y: 101.0)
let nsValue = NSValue(cgPoint: cgPoint)
var array = NSArray(object: nsValue)
// Restaurarlo de nuevo
var cgPoint : CGPoint!
for i in array {
cgPoint = i as? CGPoint
}