NSData到NSNrray的NSNumber?

时间:2017-08-29 02:46:56

标签: ios objective-c swift

我是从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相似,因为我将同时维护两个代码库。

2 个答案:

答案 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示例中做了一些更改:

  1. 如果数据不连续,则Swift示例将返回当前块中的索引。但我怀疑你想要subset内的位置,而不是当前的块。我打赌你从来没有注意到这一点,因为NSData块不是连续的很少见。

    但Swift代码看起来不正确。此Objective-C示例报告subset内的偏移量,而不是subset内当前块内的偏移量。

  2. 这不是可观察到的性能差异,但是我将newline的定义从枚举块中删除了。为什么要反复定义呢?

  3. 如果您真的在NSData中搜索某个角色,我建议您完全避免创建subset。只需使用rangeOfData:options:range:即可。这将找到你想要的任何东西。