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