gpt4 book ai didi

ios - 如何使用 CFData/NSData 在 Core Data 中存储 CFBitVector(或任何 CFType)?

转载 作者:行者123 更新时间:2023-12-01 19:18:51 25 4
gpt4 key购买 nike

我在使用 Core Foundation 类型和集合方面的经验有限,所以如果这很明显,我深表歉意。

我正在使用 CFBitVector 类型来存储一些位序列,并且我需要将其存储为二进制数据格式(以便可以将其添加到 Core Data 存储中)。最明智的做法似乎是将其存储在 CFData类型,可以通过 NSData 进行免费桥接并添加到商店,但我不确定如何执行此操作。

任何人都可以通过一个将 CFTypes 存储在 CF/NSData 中的简单示例来帮助我吗?

编辑:

这甚至是正确的方法吗?我是否应该尝试将 CFBitVector 转换为一系列 int s 哪些可以存储在数据模型中?或者也许是一个可转换的属性?

最佳答案

我最终这样做的方法是滚动我自己的属性转换器以转换 CFBitVectorRef进入 NSData实例。这样做的好处是我可以真正将位数组紧紧地塞进一个二进制数据 block 中,因为在我的情况下,我确实需要将存储大小保持在最低限度。

下面是我的 CFBitVectorTransformer 的实现类(class)。它基本上读取每个位并将它们打包到 unsigned char s(下面代码中的“段”),然后将其附加到可变 NSData缓冲。该代码适用于大于 unsigned char 的类型s,但是我想要尽可能小的 block ,以便真正最小化结果数据的大小。

#define kBitsPerByte    8


@implementation CFBitVectorTransformer


+ (Class)transformedValueClass
{
return [NSData class];
}

+ (BOOL)allowsReverseTransformation
{
return YES;
}

/* CFBitVectorRef -> NSData */
- (id)transformedValue:(id)value
{
if (!value) return nil;
if ([value isKindOfClass:[NSData class]]) return value;

/* Prepare the bit vector. */
CFBitVectorRef bitVector = (__bridge CFBitVectorRef)value;
CFIndex bitVectorCount = CFBitVectorGetCount(bitVector);

/* Prepare the data buffer. */
NSMutableData *bitData = [NSMutableData data];
unsigned char bitVectorSegment = 0;
NSUInteger bytesPerSegment = sizeof(char);
NSUInteger bitsPerSegment = bytesPerSegment * kBitsPerByte;

for (CFIndex bitIndex = 0; bitIndex < bitVectorCount; bitIndex++) {
/* Shift the bit into the segment the appropriate number of places. */
CFBit bit = CFBitVectorGetBitAtIndex(bitVector, bitIndex);
int segmentShift = bitIndex % bitsPerSegment;
bitVectorSegment |= bit << segmentShift;

/* If this is the last bit we can squeeze into the segment, or it's the final bit, append the segment to the data buffer. */
if (segmentShift == bitsPerSegment - 1 || bitIndex == bitVectorCount - 1) {
[bitData appendBytes:&bitVectorSegment length:bytesPerSegment];
bitVectorSegment = 0;
}
}

return [NSData dataWithData:bitData];
}

/* NSData -> CFBitVectorRef */
- (id)reverseTransformedValue:(id)value
{
if (!value) return NULL;
if (![value isKindOfClass:[NSData class]]) return NULL;

/* Prepare the data buffer. */
NSData *bitData = (NSData *)value;
char *bitVectorSegments = (char *)[bitData bytes];
NSUInteger bitDataLength = [bitData length];

/* Prepare the bit vector. */
CFIndex bitVectorCapacity = bitDataLength * kBitsPerByte;
CFMutableBitVectorRef bitVector = CFBitVectorCreateMutable(kCFAllocatorDefault, bitVectorCapacity);
CFBitVectorSetCount(bitVector, bitVectorCapacity);

for (NSUInteger byteIndex = 0; byteIndex < bitDataLength; byteIndex++) {
unsigned char bitVectorSegment = bitVectorSegments[byteIndex];

/* Store each bit of this byte in the bit vector. */
for (NSUInteger bitIndex = 0; bitIndex < kBitsPerByte; bitIndex++) {
CFBit bit = bitVectorSegment & 1 << bitIndex;
CFIndex bitVectorBitIndex = (byteIndex * kBitsPerByte) + bitIndex;
CFBitVectorSetBitAtIndex(bitVector, bitVectorBitIndex, bit);
}
}

return (__bridge_transfer id)bitVector;
}


@end

这很好地抽象了数据的转换,允许您只设置 CFBitVectorRef作为数据模型中的一个属性,对于大多数用途来说应该足够快。

我希望这可以帮助处于类似情况的其他人。

关于ios - 如何使用 CFData/NSData 在 Core Data 中存储 CFBitVector(或任何 CFType)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11384790/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com