web-dev-qa-db-fra.com

Comment ajouter un CGPoint à NSMutableArray?

Je veux stocker mon CGPoint dans le tableau NSMutable, j'ai donc une méthode comme celle-ci:

[self.points addObject:CGPointMake(x, y)];

Mais j'ai eu l'erreur, il a dit que:

Type incompatible pour l'argument 1 de "addObject".

Donc, je vérifie l'API,

- (void)addObject:(id)anObject

anObject Objet à ajouter à la fin du contenu du récepteur. Cette valeur ne doit pas être nulle.

Donc, je pense que le "CGPointMake" peut faire un objet, mais il ne peut pas être attribué. Ce qui se produit?

41
Tattat

Le problème est que CGPoint n'est en fait qu'une structure en C ce n'est pas un objet:

struct CGPoint {
   CGFloat x;
   CGFloat y;
};
typedef struct CGPoint CGPoint;

Si vous êtes sur l'iPhone, vous pouvez utiliser les ajouts NSValue UIKit pour convertir le CGPoint en un objet NSValue.

Voir cette réponse précédente pour des exemples: Comment puis-je ajouter facilement des objets CGPoint à un NSArray?

36
kharrison

Vous pouvez également effectuer les opérations suivantes:

[myArray addObject:[NSValue valueWithCGPoint:MyCGPoint]];
31
atbreuer11

Malheureusement pour vous, un CGPoint n'est pas un objet Objective-c. C'est une structure c. si vous Apple double-cliquez sur CGPoint, vous devez passer à la définition

struct CGPoint {
    CGFloat x;
    CGFloat y;
};
typedef struct CGPoint CGPoint;

Si vous souhaitez stocker CGPoint dans un NSArray, vous devrez d'abord les envelopper. Vous pouvez utiliser NSValue pour cela ou écrire votre propre wrapper.

voir Conversion d'un CGPoint en NSValue

EDIT> Il y a une petite surcharge pour chaque appel de méthode objective-c, et la création et la destruction d'objets impliquent de nombreux appels de méthode avant même qu'ils ne soient utilisés pour quoi que ce soit. Vous ne devriez pas vous en préoccuper normalement, mais pour les très petits objets qui encapsulent peu de comportements et qui ont une courte durée de vie, cela peut affecter les performances. Si Apple utilisait des objets pour tous les points, rect, tailles et même les pouces, les flottants, etc. les performances seraient pires.

11
hooleyhoop

Pour s'appuyer sur la réponse donnée par atbreuer11, vous pouvez convertir votre CGPoint en NSValue, le stocker dans NSMutableArray et le reconvertir en utilisant ce qui suit:

//Convert CGPoint and Store it
CGPoint pointToConvert = CGPointMake(100.0f, 100.0f);
NSValue *valueToStore = [NSValue valueWithCGPoint:pointToConvert];
NSMutableArray *arrayToKeep =[NSMutableArray arrayWithObject:valueToStore];

Ensuite, restaurez-le à nouveau:

CGPoint takeMeBack;
for (NSValue *valuetoGetBack in arrayToKeep) {
    takeMeBack = [valuetoGetBack CGPointValue];
    //do something with the CGPoint
}

C'est probablement la façon la plus simple de le faire. Vous pouvez écrire une classe complète et faire tous les types de manipulation de données, mais je pense que ce serait exagéré, à moins que vous n'ayez vraiment à le faire.

3
Septronic

Swift 3.x
// Convertir CGPoint en NSValue

let cgPoint = CGPoint(x: 101.4, y: 101.0)
let nsValue = NSValue(cgPoint: cgPoint)
var array = NSArray(object: nsValue)

// Restaurez-le à nouveau

var cgPoint : CGPoint!
for i in array {
  cgPoint = i as? CGPoint
}
0
yo2bh