Как добавить CGPoint в NSMutableArray? - PullRequest
41 голосов
/ 21 апреля 2010

Я хочу сохранить CGPoint в массиве NSMutable, поэтому у меня есть метод, подобный этому:

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

Но я получил ошибку, он сказал, что:

Несовместимый тип для аргумента 1 из "AddObject".

Итак, я проверяю API,

- (void)addObject:(id)anObject

anObject Объект, который нужно добавить в конец содержимого получателя. Это значение не должно быть ноль.

Итак, я думаю, что " CGPointMake " может создать объект, но его нельзя назначить. Что происходит?

Ответы [ 6 ]

36 голосов
/ 21 апреля 2010

Проблема в том, что CGPoint на самом деле является просто структурой C, но не объектом:

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

Если вы используете iPhone, вы можете использовать дополнения NSValue UIKit для преобразования CGPoint в объект NSValue.

См. Этот предыдущий ответ с примерами: Как можно легко добавить объекты CGPoint в NSArray?

31 голосов
/ 12 июля 2013

Вы также можете сделать следующее:

[myArray addObject:[NSValue valueWithCGPoint:MyCGPoint]];
11 голосов
/ 21 апреля 2010

К сожалению, для вас CGPoint не является объектом Objective-c. Это структура c. если вы дважды щелкаете мышью по CGPoint, вам нужно перейти к определению

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

Если вы хотите сохранить CGPoint в NSArray, вам нужно сначала обернуть их. Для этого вы можете использовать NSValue или написать свою собственную оболочку.

см. Преобразование CGPoint в NSValue

EDIT> Для каждого вызова метода target-c требуются небольшие накладные расходы, а для создания и уничтожения объектов требуется много вызовов методов, прежде чем они вообще будут использованы для чего-либо. Вы не должны беспокоиться об этом обычно, но для очень маленьких объектов, которые инкапсулируют мало поведения и имеют короткий срок службы, это может повлиять на производительность. Если бы Apple использовала объекты для всех точек, прямоугольников, размеров и даже целых, плавающих и т. Д., Производительность была бы хуже.

3 голосов
/ 25 октября 2015

Чтобы построить ответ, данный atbreuer11, вы можете преобразовать CGPoint в NSValue, сохранить его в NSMutableArray и преобразовать обратно, используя следующее:

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

Затем восстановите его снова:

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

Это, наверное, самый простой способ сделать это. Вы можете написать полный класс и выполнять все виды манипуляций с данными, но я думаю, что это будет излишним, если вам не понадобится.

0 голосов
/ 14 июля 2017

Swift 3.x
// Преобразование CGPoint в NSValue

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

// Восстановить его снова

var cgPoint : CGPoint!
for i in array {
  cgPoint = i as? CGPoint
}
0 голосов
/ 16 июля 2012

Простой способ обработки CGPoint (или любой другой не NSObject унаследованной структуры) - создать новый класс, унаследованный от NSObject.

Код длиннее, но чистый. Пример ниже:

В файле .h:

@interface MyPoint:NSObject
{
     CGPoint myPoint;   
}

- (id) init;
- (id) Init:(CGPoint) point;
- (BOOL)isEqual:(id)anObject;

@end

В файле .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

Вот пример кода, показывающий использование, не забудьте release !!!

//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");
...