2

私の地図オブジェクトには一連の座標があります。常に同じ数の座標を持つとは限りません。Java ではDouble[] xpoints、次のようにマップをインスタンス化するときに、オブジェクトを次のように宣言し、そのサイズを設定しますxpoints = new double[npoints]

Objective-Cでこれを行うにはどうすればよいですか?

私はこれをやってみました:@property(nonatomic) double * xpoints;しかし、NSLogで印刷すると、どういうわけかすべての値が0になります。

マップの初期化:

-(id)initWithXpoints:(double[]) xpointss Ypoints:(double[]) ypointss Npoints:(int)npointss
{
    self = [super init];
    if (self)
    {
        self.xpoints = xpointss;
        self.ypoints = ypointss;
        self.npoints = npointss;
    }
    return self;
}

しかし、奇妙なことが起こります。マップを作成したオブジェクトから xpoints[0] を出力すると、値がゼロに変更されます。初めて印刷するとうまくいきます。2回目はゼロを出力します。

init に送信された xpointss がメモリから削除されるために発生すると思います。ポインターの場合、xpoints プロパティを「インスタンス化」するにはどうすればよいですか?

これを行うより良い方法はありますか?

追加: 次のような一時的な xpoints を作成してみました:

double tempxpoints[npointss];
double tempypoints[npointss];
for (int i = 0; i < npointss; i++)
{
    tempxpoints[i] = xpointss[i];
    tempypoints[i] = ypointss[i];
}
self.xpoints = tempxpoints;
self.ypoints = tempypoints;

しかし、それでもうまくいきませんでした。

編集:すべての回答に感謝します。これが最終的な初期化コードになりました。

-(id)initWithXpoints:(double[]) xpointss Ypoints:(double[]) ypointss Npoints:(int)npointss
{
    self = [super init];
    if (self)
    {
         _xpoints = [[NSMutableArray alloc] init];
         _ypoints = [[NSMutableArray alloc] init];
         for (int i = 0; i < npointss; i++)
         {
             NSNumber *tempx = [NSNumber numberWithDouble:xpointss[i]];
             NSNumber *tempy = [NSNumber numberWithDouble:ypointss[i]];
             [_xpoints addObject:tempx];
             [_ypoints addObject:tempy];
         }
         _npoints = npointss;
    }
    return self;
}
4

2 に答える 2

7

配列をローカル変数として割り当てると、それらはスタックに割り当てられます。実行が関数を終了すると、それらのメモリ領域が解放されます。を使用malloc()して、受け渡しできる配列を割り当て、free()それらを解放するために使用する必要があります。

// to allocate
double[] tempxpoints = (double[])malloc(sizeof(double) * npointss);

// to free when not used any more
free(tempxpoints);

しかし実際にNSArrayは、これらのケースを処理するように設計されています。また、ARC を使用すると、メモリの解放を気にする必要さえありません。

NSMutableArray *tempxpoints = [[NSMutableArray alloc] init];
[tempxpoints addObject:@2]; // wrap the double in an NSNumber object
于 2013-08-21T18:54:22.620 に答える
3

それについて完全にObjective-Cである場合は、 を使用し、 sNSArrayで埋めNSNumber、長さを指定しないでください。通常、どのくらいのスペースが必要になるかについてヒントを与えることができますが、Objective-C のコレクションはすべて常に動的にサイズ変更されます。

コンパイラの最近のバージョンでは、array[x]表記法を使用しNSArrayて直接NSNumber定数を書くことができます@4.5f

文字通り C スタイルの配列が必要な場合は、C レベルの考え方に降りる必要があります。したがって、次のようなものです:

@property(nonatomic, readonly) double * xpoints;

と:

-(id)initWithXpoints:(double[]) xpointss Ypoints:(double[]) ypointss Npoints:(int)npointss
{
    self = [super init];
    if (self){
        size_t sizeOfArraysInBytes = sizeof(double)*npointss;
        _xpoints = (double *)malloc(sizeOfArraysInBytes);
        memcpy(_xpoints, xpointss, sizeOfArraysInBytes);
        /* ... etc ... */

        /* you never use self. notation in an init because it's a method call,
        and method calls on objects that are not yet fully instantiated aren't
        safe. Sample cause of failure: a subclass overrides the setter */
    }
    return self;
}

- (void)dealloc
{
    free(_xpoints);
    /* ... etc ... */
}

配列自体は、他の場所で読み書きできます(それが指すものではなく、読み取り専用のポインターです)class.xpoints[0]など.

于 2013-08-21T18:54:37.270 に答える