【问题标题】:NSMutableData remove bytes?NSMutableData 删除字节?
【发布时间】:2010-02-27 00:02:47
【问题描述】:

我可以使用appendData 方法轻松地将字节添加到 NSMutableData 实例,但是我没有看到任何类似的删除数据的方法?我是否忽略了某些内容,还是需要创建一个新对象并仅复制我需要的字节?

【问题讨论】:

    标签: objective-c nsdata nsmutabledata


    【解决方案1】:

    请看以下方法的文档:

    - (void)replaceBytesInRange:(NSRange)range withBytes:(const void *)replacementBytes length:(NSUInteger)replacementLength
    

    Apple 明确表示:

    如果范围的长度不等于 替换长度,接收者是 调整大小以适应新字节。 接收器中超出范围的任何字节 被转移以适应新的 字节。因此,您可以将 NULL 传递给 replaceBytes 和 0 为 replacementLength 删除字节 接收器在范围范围内。你 也可以替换一个范围(这可能 长度为零),字节数多于 范围的长度,它具有 插入的效果(或“替换一些 并插入更多”)。

    要从末尾删除 10 个字节,请使用:

    [data setLength:[data length] - 10];
    

    也可以通过 replaceBytesInRange 完成,但实际上速度要快得多,因为字节并没有真正删除。相反,仅更改了内部大小变量,并且 NSMutableData 的行为就像删除了字节一样。 IOW,这是一个 O(1) 操作(这意味着无论您删除多少字节,它总是需要同样长的时间来执行),而且速度非常快。

    要从前面删除 10 个字节,请使用:

    [data replaceBytesInRange:NSMakeRange(0, 10) withBytes:NULL length:0];
    

    要删除中间的 10 个字节(例如,在 20 个字节之后),请使用:

    [data replaceBytesInRange:NSMakeRange(20, 10) withBytes:NULL length:0];
    

    replaceBytesInRange 是一个 O(n) 操作。这意味着无论删除 100 个字节需要多长时间,删除 200 个字节需要两倍的时间,依此类推。它仍然非常快,并且仅受计算机内存 (RAM) 吞吐量的限制。如果您有 10 MB 的数据并从前面删除 1 MB,则会复制 9 MB 以填补刚刚删除的 MB 的空白。因此,操作的速度取决于您的系统将 9 MB RAM 从一个地址移动到另一个地址的速度。这通常足够快,除非您处理包含数百 MB 的 NSMutableData 对象。

    【讨论】:

    • 这是一个很好的答案,尽管它是一个答案的派生,它的支持率较低并且现在无关紧要。您是否可以对其进行修改以使其成为独立的答案? +1
    • @Yar:当然,为什么不呢。我删除了对另一个答案的引用。
    • 不知何故我今天回到了这个答案,正在寻找“你也可以用比范围长度更多的字节替换一个范围(可能是零长度),它的效果是插入(或“替换一些并插入更多”)。”切线但相关。谢谢!
    • 我用这些方法去掉了前面两个字节,最后一个字节。非常有用 - 可能是大型数据集的内存密集型。但是效果很好……
    • 但是当我想从前面删除数据时呢?
    【解决方案2】:

    由于 NSMutableData 与 CFMutableDataRef 是免费桥接的,因此您可以使用 CFDataDeleteBytes() 函数:

    NSMutableData *data = ...
    CFDataDeleteBytes((CFMutableDataRef)data, CFRangeMake(3, 4));
    

    【讨论】:

    • 小心。在这条道路上存在性能问题。如果您编辑的次数相对较少或使用少量数据,那没什么大不了的。任何更大、频繁或性能敏感的数据,请考虑使用某种类型的优化数据结构。
    • 谢谢,效果很好。你怎么知道 NSMutable 数据与 CFMutableDataRef 是“免费桥接”的?我在 NSMutableData 文档中没有看到任何提及这一点?
    • 如果您查看 NSMutableData 文档developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Reference/… 的“概述”部分,您会在第二段中看到它
    • 为什么使用CoreFoundation,如果你可以使用NSMutableData方法replaceBytesInRange,根据文档删除范围内的字节,如果替换字节指针为NULL并且替换长度也是0?
    • 虽然此解决方案有效,但我认为 Mecki's 更清洁,应标记为已接受。 +1 给 Mecki,但这里没有找到第二个最佳解决方案。 (如果在幕后知道一种解决方案是否使用另一种解决方案会很有趣!:)
    【解决方案3】:

    如果要删除的数据在末尾,可以使用

    [NSMutableDataInstance setLength:[NSMutableDataInstance length] - n];

    或使用 obj-c 2.0 语法

    NSMutableDataInstance.length -= n;
    

    对于任何比我建议处理原始数据更复杂的事情。

    【讨论】:

    • 感谢您的提示!然而,我试图从前面移除:)
    【解决方案4】:

    我看到这个帖子有答案,但这可能是有价值的补充。要从 NSMuttableData 中删除所有字节,您可以创建新数据并将其复制到原始数据:

    [myData setData:[NSData dataWithBytes:NULL length:0]];
    

    这很好用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多