我是从Swift转到Objective-C而我遇到的一个问题是NSData似乎没有像Swift数据那样枚举UInt8值的方法。存在类似标题的其他答案但它们都处理属性列表,而我只有一桶ASCII字节。具体来说,我想在Obj-C中复制的代码是:
//Find the next newline in ASCII data given a byte offset
let subset = myData.advanced(by: offset)
var lineEnd: Data.Index = myData.endIndex
subset.enumerateBytes({ (memory, idx, stop) in
let newline: UInt8 = 10
for idx in memory.indices {
let charByte = memory[idx]
if charByte == newline {
lineEnd = idx
stop = true; return;
}
}
})
理想情况下,我想要一种方法将NSArray转换为NSNumber数组,我可以从中提取intValues。当然,如果有更好的方法,请告诉我。目标是使Obj-C代码尽可能与Swift相似,因为我将同时维护两个代码库。
答案 0 :(得分:1)
访问NSData
字节的唯一好方法是调用其-bytes
方法,该方法会为您提供指向其内部存储的C指针。
NSData *data = ...;
const uint8_t *bytes = data.bytes;
NSUInteger length = data.length;
for (NSUInteger i = 0; i < length; i++) {
uint8_t byte = bytes[i];
// do something with byte
}
答案 1 :(得分:0)
与advance
最接近的是subdataWithRange
。等同于enumerateBytes
的是enumerateByteRangesUsingBlock
。它会产生类似的东西:
NSData *subset = [data subdataWithRange:NSMakeRange(offset, data.length - offset)];
__block NSUInteger lineEnd = data.length;
Byte newline = 10;
[subset enumerateByteRangesUsingBlock:^(const void * _Nonnull bytes, NSRange byteRange, BOOL * _Nonnull stop) {
for (NSInteger index = 0; index < byteRange.length; index++) {
Byte charByte = ((Byte *)bytes)[index];
if (charByte == newline) {
lineEnd = index + byteRange.location;
*stop = true;
return;
}
}
}];
注意,我从你的Swift示例中做了一些更改:
如果数据不连续,则Swift示例将返回当前块中的索引。但我怀疑你想要subset
内的位置,而不是当前的块。我打赌你从来没有注意到这一点,因为NSData
块不是连续的很少见。
但Swift代码看起来不正确。此Objective-C示例报告subset
内的偏移量,而不是subset
内当前块内的偏移量。
这不是可观察到的性能差异,但是我将newline
的定义从枚举块中删除了。为什么要反复定义呢?
如果您真的在NSData
中搜索某个角色,我建议您完全避免创建subset
。只需使用rangeOfData:options:range:
即可。这将找到你想要的任何东西。