41

我想将我的 CGPoint 存储到 NSMutable 数组中,所以,我有这样的方法:

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

但我得到了错误,它说:

“addObject”的参数 1 的类型不兼容。

所以,我检查了API,

- (void)addObject:(id)anObject

anObject 添加到接收者内容末尾的对象。该值不能为零。

所以,我认为“ CGPointMake ”可以制作一个对象,但它不能被分配。发生什么了?

4

6 回答 6

36

问题是 CGPoint 实际上只是一个 C 结构它不是一个对象:

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

如果您在 iPhone 上,您可以使用 NSValue UIKit 添加将 CGPoint 转换为 NSValue 对象。

有关示例,请参见先前的答案:如何以简单的方式将 CGPoint 对象添加到 NSArray?

于 2010-04-21T16:29:14.733 回答
32

您还可以执行以下操作:

[myArray addObject:[NSValue valueWithCGPoint:MyCGPoint]];
于 2013-07-12T16:24:19.600 回答
11

不幸的是,CGPoint 不是 Objective-c 对象。它是 ac 结构。如果你苹果双击 CGPoint 你应该跳到定义

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

如果要将 CGPoint 存储在 NSArray 中,则需要先将它们包装起来。您可以为此使用 NSValue 或编写自己的包装器。

请参阅将 CGPoint 转换为 NSValue

编辑>每个objective-c方法调用都有一点开销,创建和销毁对象涉及到许多方法调用,甚至在它们被用于任何事情之前。您通常不应该担心这一点,但对于封装了很少行为并且生命周期很短的非常小的对象可能会影响性能。如果 Apple 对所有点、矩形、大小甚至整数、浮点数等都使用对象,性能会更差。

于 2010-04-21T16:28:53.340 回答
4

要基于 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
}

这可能是最简单的方法。您可以编写一个完整的类并进行所有类型的数据操作,但我认为这将是一种矫枉过正,除非您真的必须这样做。

编辑

对于 Swift 5(我不确定为什么要这样做,因为我们现在可以使用文字数组,但是这里是):

保存值:

let somePoint = CGPoint(x: 200, y: 400)
let array = NSMutableArray(array: [somePoint])

要检索它:

let points = array.compactMap({ ($0 as? NSValue)?.cgPointValue })
于 2015-10-25T15:52:15.793 回答
0

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
}
于 2017-07-14T07:25:54.797 回答
-1

处理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

这是一些显示用法的代码示例,不要忘记发布

//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");
于 2012-07-16T01:56:34.780 回答