2016-05-01 20 views
0

std :: vectorをNSDataに格納して直そうとしています。私の最初の試みはNSValueに各点を変換し、ひどく非効率なNSKeyedUnarchiverでそれらを保存しました。私のテストデータセットは64MBの人間が読めるテキスト(NSKeyedUnarchiver)を必要とし、各std:vectorをNSDataに変換するのに比べて、結果として得られる格納ファイルはもっと妥当な896kbです。私は、データを格納するために、次のようにやっている:NSDataからのstd :: vectorの保存と復元

typedef std::vector<CGPoint> CGContour; 
    typedef std::vector<std::vector<CGPoint>> CGContours; 
    static CGContours contoursVector; 

    contoursVector = CGContours(1024); //Populated with CGContours that are populated with CGPoints datatypes above 

    //doing the following in a for loop, just showing record 0 for brevity 
    NSData *contourData([[NSData alloc] 
         initWithBytesNoCopy: contoursVector[0].data() 
         length: contoursVector[0].size() 
         freeWhenDone:false]); 

私はバッファを取得することができる午前:

const void *buffer = [contourData bytes]; 
    size_t len = [contourData length]; 

はしかし、私はSTDを移入する方法を見つけ出すことができません::持つベクトルをconst voidバッファポインタ。私は、私は考えることができるすべての可能なポインタと間接参照の組み合わせを使用して試してみました - 私はコンパイルするために得ることができる唯一のことは、これです:

contoursVector[0] = *(CGContour *)[contourData bytes]; 

私ははっきりと、何かを彼らは0,0ですCGPointsのベクトルを検査した場合そうではありません。

EDIT:提案された回答を実装した後、時にはEXC_BAD_ACCESSを取得することもあります。ここでは、関連するバックトレースは次のとおりです。

* thread #17: tid = 0x11bf7d4, 0x0000000111607551 libsystem_platform.dylib`_platform_memmove$VARIANT$Ivybridge + 49, queue = 'NSOperationQueue 0x7fa298f51000 :: NSOperation 0x7fa29f3251f0 (QOS: UTILITY)', stop reason = EXC_BAD_ACCESS (code=1, address=0x126e27000) 
frame #0: 0x0000000111607551 libsystem_platform.dylib`_platform_memmove$VARIANT$Ivybridge + 49 
frame #1: 0x000000010d01890f Foundation`NSCopyMemoryPages + 57 
frame #2: 0x000000010cf9b737 Foundation`_NSDataCreateVMDispatchData + 103 
frame #3: 0x000000010cf99cf2 Foundation`-[_NSPlaceholderData initWithBytes:length:copy:deallocator:] + 230 
frame #4: 0x000000010cfa5902 Foundation`-[NSData(NSData) initWithBytes:length:] + 37 
* frame #5: 0x000000010cfeabfb Foundation`+[NSData(NSData) dataWithBytes:length:] + 54 
frame #6: 0x000000010c5c998a TDTPhotoLib`storePointData() + 682 at TDTContourImage.mm:562 

奇妙なことは、輪郭とデータの両方に変換された輪郭の両方で、時にはそれがない他の回動作します(デバッガで有効になり、問題が断続的であると思われます私はすべてのポイントを反復処理することができていますが、それはNSDataのライン上でクラッシュし

:何が異なる場合があります場合は)

EDIT 2をどのように伝えることができません。

NSMutableArray<NSData *> *groupedPointsArrayMain = [NSMutableArray new]; 

for(const CGContour &contour : contoursVector) 
{ 
    if (contour.size() > 0) { 

     // I am able to iterate over every point and store them this way 
     NSMutableArray *contourPoints = [NSMutableArray arrayWithCapacity:contour.size()]; 

     for(const CGPoint &point : contour) 
     { 
      [contourPoints addObject:[NSValue valueWithCGPoint:point]]; 
     } 

     //When it crashes, it will crash on this line 
     //despite it successfully walking over each point 
     //in the code directly above 
     NSData *data = [NSData dataWithBytes: contour.data() 
             length: (contour.size() * cgContourSize)]; 

     [groupedPointsArrayMain addObject:data]; 
    } 
} 

答えて

1

このような何かがトリックを行う必要があります。私がLinux atmにいるので、このコードをコンパイルしようとしなかったことに注意してください。

typedef std::vector<CGPoint> CGContour; 
typedef std::vector<CGContour> CGContours; 

const size_t contourSize = sizeof(CGContour); 

NSMutableArray<NSData *> *datas = [NSMutableArray new]; 

{ // store 
    CGContours contours(1024); 

    for(const CGContour &contour : contours) 
    { 
    NSData *data = [NSData dataWithBytes: contour.data() 
            length: contour.size() * contourSize]; 
    [datas addObject:data] 
    } 
} 

{ // restore 
    CGContours contours; 

    for(NSData *data in datas) 
    { 
    const size_t count = [data length]/contourSize; 
    CGPoint *first = (CGPoint *)[data bytes]; 
    CGPoint *last = first + count; 

    contours.emplace_back(first, last); 
    } 
} 
+0

おかげで - 私はそれに打撃を与えたが、据え付けるラインはLLVMのメモリエラーで失敗するコンパイル原因:メモリ:1731:31:「のstd :: __ 1 ::ベクトル<の初期化に該当するコンストラクタをするCGPoint 、std :: __ 1 :: allocator > '何かアイデア?コンパイルするには&& contourの代わりに1つの "&"だけを使用しなければならないことに注意してください。 –

+0

あなたの例で*最初に調べると、size()は0だが、データは有効な(136416)バイトを持っていると書かれています。おそらくそれはポインタなので、私はそれを言及すべきだと思った。 –

+0

@ JeshuaLacock私は自分の答えを修正しました。私は二日酔いをしている間にこの質問に答えることをお詫びします。 –

関連する問題