【问题标题】:How do I add a CGPoint to NSMutableArray?如何将 CGPoint 添加到 NSMutableArray?
【发布时间】:2011-02-10 16:26:09
【问题描述】:

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

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

但我得到了错误,它说:

参数 1 的类型不兼容 “添加对象”。

所以,我检查了 API,

- (void)addObject:(id)anObject

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

所以,我认为“CGPointMake”可以制作一个Object,但不能赋值。会发生什么?

【问题讨论】:

标签: iphone objective-c nsarray cgpoint


【解决方案1】:

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

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

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

有关示例,请参见之前的答案:How can I add CGPoint objects to an NSArray the easy way?

【讨论】:

  • 考虑两种方法之间的区别:valueWithCGPoint:valueWithPointer:Details here
【解决方案2】:

您还可以执行以下操作:

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

【讨论】:

    【解决方案3】:

    很遗憾,CGPoint 不是 Objective-c 对象。它是一个 c 结构。如果你苹果双击 CGPoint 你应该跳转到定义

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

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

    Converting a CGPoint to NSValue

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

    【讨论】:

      【解决方案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 })
      

      【讨论】:

        【解决方案5】:

        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
        }
        

        【讨论】:

          【解决方案6】:

          处理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");
          

          【讨论】:

            猜你喜欢
            • 2011-12-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多