Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从NSData存储和恢复std::vector_C++_Objective C_Nsdata_Stdvector - Fatal编程技术网

C++ 从NSData存储和恢复std::vector

C++ 从NSData存储和恢复std::vector,c++,objective-c,nsdata,stdvector,C++,Objective C,Nsdata,Stdvector,我试图将std::vector存储到NSData并直接返回。我的第一次尝试是将每个点转换为一个NSValue,并使用NSKeyedUnachiver存储它们,这似乎效率极低。我的测试数据集需要64MB的人类可读文本(使用NSKeyedUnarchiver),而将每个std:vector转换为NSData生成的存储文件需要896kb。我按照以下步骤存储数据: typedef std::vector<CGPoint> CGContour; typedef std::vec

我试图将std::vector存储到NSData并直接返回。我的第一次尝试是将每个点转换为一个NSValue,并使用NSKeyedUnachiver存储它们,这似乎效率极低。我的测试数据集需要64MB的人类可读文本(使用NSKeyedUnarchiver),而将每个std:vector转换为NSData生成的存储文件需要896kb。我按照以下步骤存储数据:

    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缓冲区指针填充std::vector。我已经尝试使用我能想到的所有可能的指针和解引用组合-我唯一能编译的是:

   contoursVector[0] = *(CGContour *)[contourData bytes];
如果我检查CGPoints的向量,它们是0,0,显然有些地方不对

编辑:在实现建议的答案后,有时它会起作用,有时我会获得EXC\u BAD\u访问权限。以下是相关的回溯:

* 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
奇怪的是,等高线和转换为数据的等高线在调试器中看起来都是有效的,问题似乎是间歇性的(有时有效,有时无效,但无法判断是否有任何不同)

编辑2:

我可以迭代每个点,但它在NSData线上崩溃

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];
    }
}
NSMutableArray*groupedPointsArrayMain=[NSMutableArray new];
用于(const CGContour和contour:contoursVector)
{
如果(轮廓.size()>0){
//我能够迭代每个点并以这种方式存储它们
NSMutableArray*contourPoints=[NSMutableArray阵列容量:contour.size()];
用于(常量点和点:等高线)
{
[contourPoints添加对象:[NSValue valueWithCGPoint:point]];
}
//当它崩溃时,它会在这条线上崩溃
//尽管它成功地跨越了每一点
//在上面的代码中
NSData*data=[NSData dataWithBytes:contour.data()
长度:(轮廓.size()*cgContourSize)];
[groupedPointsArrayMain添加对象:数据];
}
}

像这样的东西应该可以奏效。请注意,我没有尝试编译此代码,因为我使用的是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);
  }
}
typedef标准::矢量轮廓;
typedef std::矢量轮廓;
常量大小\u t轮廓大小=大小(CGContour);
NSMUTABLEARRY*数据=[NSMUTABLEARRY new];
{//商店
cg(1024);
用于(等高线常数和等高线:等高线)
{
NSData*data=[NSData dataWithBytes:contour.data()
长度:轮廓.size()*轮廓尺寸];
[数据添加对象:数据]
}
}
{//restore
CG等高线;
用于(NSData*数据中的数据)
{
常量大小\u t计数=[数据长度]/轮廓大小;
CGPoint*first=(CGPoint*)[数据字节];
CGPoint*last=第一个+计数;
等高线。向后放置(第一个,最后一个);
}
}

谢谢-我尝试了一下,但emplace行导致编译失败,出现LLVM内存错误:内存:1731:31:没有匹配的构造函数初始化'std::\uu 1::vector'有什么想法吗?请注意,我只需要使用一个“&”,so&contour而不是&&contour,它也可以编译。如果我在您的示例中首先检查*的话,它会声明size()为0,但是数据有有效的(136416)字节。也许是因为它是一个指针,但我想我应该提到它。@JeshuaLacock我修正了我的答案,我很抱歉在我宿醉时回答了这个问题。非常感谢你的帮助。宿醉或无宿醉;我会接受所有我能得到的帮助!干杯。这对我来说似乎是断断续续的,你愿意看看我编辑中的回溯吗?似乎与自动释放有关(即中汇编代码中导致EXC_BAD_访问的行的注释)。
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);
  }
}