2011-02-18 16 views
3

cでは、浮動小数点数の配列(たとえば)が必要だった場合、固定サイズを定義して割り当てるだけで、数学演算の各要素にアクセスできます。しかし、私は配列が変更可能になることを望んでいます。なぜなら、NSMutableArrayのアイデアは素晴らしく、アプリケーションが実行されていて配列が簡単に10000以上の要素を超えてしまうからです。しかし、(私が正しく理解していれば)オブジェクトだけを格納しているので、NSNumberに数値をラップして配列に入れなければなりません。これは、浮動小数点数(または倍数または整数)の配列を格納するだけのばかげたオーバーヘッドのように思えます。ココアでの浮動小数点配列の使用/格納

一方、Core Dataにはflout属性があることがわかりますが、同じ方法(配列[index])でこれにどのようにアクセスできるかわかりません。私はここに何かを逃していますかすべての重たい数学を固定サイズのC配列で行うだけで、私が遭遇したことのない基礎クラスを使う方法や、配列にアクセスするようなコアデータオブジェクトにアクセスする方法はありますか?

+0

オリジナルのポスターがiPhone/Cocoa-Touch向けに開発されている場合でも、これはココアの問題であるため、「ココア」と付け替えられます。 – westsider

答えて

1

ここには何もありません。 Cスカラー型の配列のための正式なobjcインターフェースはありません。

std::vectorを使用し、CF/NS-Dataなどのメカニズムを使用してシリアライズ/デシリアライズを実装するのが簡単な方法です(ウェスタンサ)。あなたがにObjCインターフェイスでのstd ::ベクトルをラップすることができ

あなたが望んでいた場合、:

/* MONDoubleArray.h */ 

/* by using pimpl, i'm assuming you are not building everything as objc++ */ 
struct t_MONDoubleArray_data; 

@interface MONDoubleArray : NSObject < NSCoding, NSCopying, NSMutableCopying > 
{ 
    t_MONDoubleArray_data* data; 
} 

- (double)doubleAtIndex; 
- (void)setDoubleAtiIndex:(double)index; 
- (NSUInteger)count; 

/*...*/ 

@end 

/* MONDoubleArray.mm */ 

struct t_MONDoubleArray_data { 
    std::vector<double> array; 
}; 

@implementation MONDoubleBuffer 

- (id)init 
{ 
    self = [super init]; 
    if (0 != self) { 
    /* remember your c++ error handling (e.g., handle exceptions here) */ 
     array = new t_MONDoubleArray_data; 
     if (0 == array) { 
      [self release]; 
      return 0; 
     } 
    } 
    return self; 
} 

/*...more variants...*/ 

- (void)dealloc 
{ 
    delete array; 
    [super dealloc]; 
} 

- (NSData *)dataRepresentationOfDoubleData { /*...*/ } 
- (void)setDoubleDataFromDataRepresentation:(NSData *)data { /*...*/ } 

/*...*/ 

@end 

を、その後、あなたは手間をかけずにObjC直列化を達成してきたと思います。

@interface MONFloatBuffer : NSObject 
{ 
    NSMutableArray * floats; 
} 

@end 

@implementation MONFloatBuffer 

- (id)init 
{ 
    self = [super init]; 
    if (0 != self) { 
     CFAllocatorRef allocator = 0; /* default */ 
     CFIndex capacity = 0; /* resizable */ 
     /* you could implement some of this, if you wanted */ 
     const CFArrayCallBacks callBacks = { 0 /* version */ , 0 /* retain */ , 0 /* release */ , 0 /* copyDescription */ , 0 /* equal */ }; 
     floats = (NSMutableArray*)CFArrayCreateMutable(allocator, capacity, &callBacks); 
     // now we can read/write pointer sized values to `floats`, 
     // and the values won't be passed to CFRetain/CFRelease. 
    } 
    return self; 
} 

@end 

しかし、それはまだ適切にカスタマイズすることなく、自分自身をデシリアライズするために失敗します:

は、ポインタ(または狭い)サイズのエントリを使用して、また、スカラー用CF/NS_MutableArrayを使用する方法があります。だから... NSPointerArrayはをもっと手に入れます。 ...しかし、あなたはまだポインタサイズの値に固定されているので、あなた自身で書く必要があります。それほど難しいことではありません。欠点は、あなたが最終的に結婚する可能性のある変異の数です。

+0

ありがとうございます。それをobjcインターフェースにラップするのはいいです。私は[array index:index]の単純な配列[index]の使い方を失っています(面白く見えます)。私は最初の例を取っ​​た(いくつかの問題を修正した)。そしてそれはそれ自身で罰金に従います(まだメソッドとプロトコルを追加する必要があります)。しかし、MONDoubleArray * doubleArrayを追加すると、私はMONDoubleArray.hにエラーが発生します:「 't_MONDoubleArray_data'の前に特定のqualifer-listが必要です」というエラーが表示されます。そして、私は徹底的に説明するために、徹夜で調べました。何かご意見は? –

+0

さて、デリゲートをmからmmに変更しました。しかし、objC++としてそれを使用するクラスをまだコンパイルしなければならない場合、objcインタフェースでそれをラップするポイントは何ですか?他のクラスをobjC++としてコンパイルする際にパフォーマンス上の問題はありますか? –

+0

うまくいけば、構文を簡単にしたいクラスにメソッドを追加できます。また、C++を使用してベクターを公開することもできます(クラスを参照するすべての翻訳をobjC++に切り替えることを前提とします)。エラーまで、ヘッダーのために投稿したコードは、(typo 'setDoubleAtiIndex'を除いて)okと思われます。おそらくコードを投稿し、エラーが発生した行を指摘するべきでしょうか?それがここで起こるなら 'struct t_MONDoubleArray_data {std :: vector 配列; }; '、その部分はMONDoubleArray.mmにあるはずです。それはC++なので、c/objc変換のコンパイルは失敗します。 – justin

1

NSNumberで浮動小数点数をラップしたり、NSMutableArraysを使用したりしないでください。あなたが言うように、これはオーバーヘッドのばかげた量を追加します。

C++標準テンプレートライブラリ(STL)コンテナの使用をお勧めします。あなたの場合、vectorが最適でしょう。

STLの使用は、Objective-CからObjective-C++への移行を意味します。また、影響を受けるソースファイルの拡張子を.mから.mmに変更するだけでなく、#importをstdを使用するファイルに追加する必要があります::ベクター。

もう1つのアプローチはNSMutableDataオブジェクトを使用することですが、おそらくデータの追加(浮動小数点数)の追加を行うことになります。

関連する問題