41

CGPoint を NSMutable 配列に保存したいので、次のような方法があります。

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

しかし、私はエラーを受け取りました、それは言った:

「addObject」の引数 1 の型に互換性がありません。

APIを調べてみると

- (void)addObject:(id)anObject

anObject レシーバーのコンテンツの最後に追加するオブジェクト。この値は nil であってはなりません。

ですから、「 CGPointMake 」はオブジェクトを作成できると思いますが、割り当てはできません。何が起こるのですか?

4

6 に答える 6

36

問題は、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?

于 2010-04-21T16:29:14.733 に答える
32

次のこともできます。

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

残念ながら、CGPoint は Objective-c オブジェクトではありません。ac構造体です。Apple が CGPoint をダブルクリックすると、定義にジャンプする必要があります。

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

CGPoint を NSArray に格納する場合は、最初にそれらをラップする必要があります。これには NSValue を使用するか、独自のラッパーを作成できます。

CGPoint を NSValue に変換するを参照してください。

EDIT> object-c メソッド呼び出しごとに小さなオーバーヘッドがあり、オブジェクトの作成と破棄には、何かに使用される前に多くのメソッド呼び出しが含まれます。通常はこれについて心配する必要はありませんが、動作がほとんどカプセル化されておらず、寿命が短い非常に小さなオブジェクトの場合、パフォーマンスに影響を与える可能性があります。Apple がすべてのポイント、rect、サイズ、さらには int、float などにオブジェクトを使用すると、パフォーマンスが低下します。

于 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 に答える
-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 に答える