使用 Swift 从 NSData 中获取数据

2024-01-08

我正在寻找Swift and NSData成为一场令人沮丧的邪恶婚姻。我发现每次处理这件事时,我都觉得所有所谓的新发现的 Swift 安全性都消失了。崩溃的数量(带有无用的痕迹)没有帮助。

所以,我了解到,我可以避免可怕的事情UnsafeMutablePointer通过执行以下操作:

var bytes = [UInt8](count: 15, repeatedValue: 0)
anNSData.getBytes(&bytes, length=15)

我还发现,我可以直接提取奇异值:

var u32:UInt32 = 0
anNSData.getBytes(&u32, length=4)

这引出了两个中间问题:

1)我可以使用比硬编码常量更可靠的东西吗?如果这是C,我就用sizeof。但我想我读到也许我应该使用strideof反而sizeof?那行不通[UInt8]的,会吗?

2)文档(对于 Swift)说这个参数应该是_ buffer: UnsafeMutablePointer<Void>。那么这是如何运作的呢?我只是运气好而已吗?为什么我想要这样做而不是更本机/托管的 [Uint8] 构造?我想知道是否UnsafeMutablePointer是一个协议,但它是一个结构。

有了直接读取值(而不是作为数组)的勇气,我想也许我可以尝试另一种结构。我有一个 6 字节结构,如下所示:

struct TreeDescription : Hashable {
    var id:UInt32 = 0x00000000
    var channel:UInt8 = 0x00
    var rssi:UInt8 = 0x00

    var hashValue:Int {
        return Int(self.id)
    }
}

这确实有效(在认为它不起作用之后,但最终进行了清理,这使得一些崩溃消失了)!

var tree = TreeDescription()
anNSData.getBytes(&newTree, length: 6)

但这让我担心结构包装细节?为什么这有效?这样做我应该担心什么?

这对我来说感觉非常 C 风格。我认为 Swift 取代了 ObjectiveC 中的 C。


您可能想查看RawData https://github.com/krzyzanowskim/RawData这确实是新的,这个家伙只是对这个想法进行了一些实验,所以不要认为它已经测试得很好或者什么,有些功能甚至还没有实现。它基本上是(你猜对了)原始数据(一系列字节)的 Swift-y 包装器。

使用此扩展,您可以使用以下命令对其进行初始化NSData实例:

extension RawData {
    convenience init(data: NSData) {
        self.init(UnsafeMutableBufferPointer(start: UnsafeMutablePointer(data.bytes), count: data.length))
    }
}

你可以这样称呼它:

let data = "Hello, data!".dataUsingEncoding(NSASCIIStringEncoding)!

let rawData = RawData(data: data)

编辑:回答你的问题:

问题是数据可能很大,非常大。您通常不想复制大的内容,因为空间很宝贵。数组之间的区别[UInt8]价值观和NSData例如,每次将数组赋予函数 -> 新副本,进行赋值 -> 新副本时,都会复制数组。对于大数据来说,这并不是很理想的情况。

1)如果你想要最原生、最安全的方式,而不需要任何第三方库,如上面提到的,你可以这样做:

let data = UnsafeMutableBufferPointer(start: UnsafeMutablePointer(data.bytes), count: data.length)

(我知道这听起来不太安全,但请相信我)。您几乎可以像普通数组一样使用它:

let data = "Hello, data!".dataUsingEncoding(NSASCIIStringEncoding)!

let bytes = UnsafeMutableBufferPointer(start: UnsafeMutablePointer<UInt8>(data.bytes), count: data.length)

for byte in bytes {}
bytes.indexOf(0)
bytes.maxElement()

并且当您传递数据时它不会复制数据。

2) UnsafeMutablePointer<Void>确实非常像 C,在这种情况下,它表示指针序列中的起始值(也称为基数)。这Voidtype 也来自 C,这意味着指针不知道它存储的是什么类型的值。您可以将各种指针强制转换为您期望的类型,如下所示:UnsafeMutablePointer<Int>(yourVoidPointer)(这不应该崩溃)。如前所述,您可以使用UnsafeMutableBufferPointer将其用作您类型的集合。UnsafeMutableBufferPointer只是你的基指针和长度的包装(这解释了我使用的初始化程序)。

将数据直接解码到结构中的方法确实有效,即使在编译后,结构的属性也处于正确的顺序,并且结构的大小正是其存储的属性的总和。对于像您这样的简单数据来说,这完全没问题。还有一个替代方案:使用NSCoding协议。优点:更安全。缺点:你必须继承 NSObject 的子类。我认为你应该坚持现在的做法。我要改变的一件事是将结构的解码放入结构本身并使用sizeof。像这样:

struct TreeDescription {
    var id:UInt32 = 0x00000000
    var channel:UInt8 = 0x00
    var rssi:UInt8 = 0x00

    init(data: NSData) {
        data.getBytes(&self, length: sizeof(TreeDescription))
    }
}

另一个编辑:您始终可以从Unsafe(Mutable)Pointer<T>用方法memory其返回类型是T。如果需要,您可以随时通过添加/减去来移动指针(例如获取下一个值)Ints to it.

编辑回答您的评论:您使用&通过inout变量,然后可以在函数内对其进行修改。因为一个inout变量与传递指针基本相同,Swift 开发人员决定让传递成为可能&value对于一个期望的参数UnsafeMutablePointer。示范:

func inoutArray(inout array: [Int]) {}

func pointerArray(array: UnsafeMutablePointer<Int>) {}

var array = [1, 2, 3]

inoutArray(&array)
pointerArray(&array)

这也适用于structs(也许还有其他一些事情)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Swift 从 NSData 中获取数据 的相关文章

  • 如何使用 SwiftUI 获取多个屏幕上的键盘高度并移动按钮

    以下代码获取键盘显示时的键盘高度 并将按钮移动键盘高度 在转换源 ContentView 和转换目标 SecibdContentView 处以相同的方式执行此移动 但按钮在转换目标处不移动 如何使按钮在多个屏幕上移动相同 import Sw
  • 二元运算符“/”不能应用于两个(Int)操作数[重复]

    这个问题在这里已经有答案了 我得到了Binary operator cannot be applied to two Int operands当我将以下代码放入 Xcode 中的 Swift Playground 时出错 func sumO
  • 如何使用 Swift 将“完成”按钮添加到 iOS 中的数字键盘?

    它在默认键盘上工作得很好 但我无法让它在数字键盘上工作 有任何想法吗 据我所知 你不能在键盘部分添加 完成 按钮 你应该添加一个inputAccessoryView to the UITextField or UITextView 如果这就
  • 使用 BGTaskScheduler 进行后台获取与调试模拟完美配合,但在实践中却不起作用

    我在 appDelegate 的 didFinishLaunchingWithOptions 中注册后台获取任务 BGTaskScheduler shared register forTaskWithIdentifier Backgroun
  • Swift:协议、结构、类

    我开始学习 Swift 语言 但在理解协议 结构和类方面遇到了困难 我来自 Android 方面的编程 所以我相信 Swift 协议基本上是 Java 接口 其中每一个的正确用例是什么 这些类比并不 完全 正确 但这就是我所理解的要点 是的
  • 以类型化内存视图作为成员的结构定义

    目前我正在尝试让一个具有类型化内存视图的结构能够工作 例如 ctypedef struct node unsigned int inds 如果 inds 不是内存视图 据我所知 它可以完美地工作 然而 通过内存视图并使用类似的东西 def
  • 在 UITableView 的部分标题文本下方添加一些边距

    我已经设计了标题文本的样式 func tableView tableView UITableView cellForRowAtIndexPath indexPath NSIndexPath gt UITableViewCell let ce
  • WKWebview 中的 iCLoud 文档选择器关闭容器视图

    我有一个 WKWebview 加载基于 Web 的 UI 我希望用户能够从其 iCloud 文档上传文件 我已授予正确的权限 并且可以浏览 iCloud 文档 但是 当我选择文件或单击取消按钮时 文档选择器视图也会关闭 WKWebview
  • 如何观察UserDefaults的变化?

    我有一个 ObservedObject在我看来 struct HomeView View ObservedObject var station Station var body some View Text self station sta
  • 如何在 Swift 中使用未知密钥解码 JSON 响应?

    我想将数据拆分为https blockchain info ticker https blockchain info ticker这样每一行都是它自己的String在一个数组中 我正在制作一个获取所选货币价格的应用程序 因此 如果有人想要澳
  • 如何右对齐 UILabel?

    Remark 实施 myLabel textAlignment right does not解决了我的问题 这不是我所要求的 我想要实现的是让标签对齐右对齐 为了更清楚地说明 这就是如何left对齐外观 就是这样justify对齐外观 if
  • 在 swift 中将简单字符串转换为 JSON 字符串

    我知道有一个同标题的问题here https stackoverflow com questions 30825755 convert string to json string in swift 但在那个问题中 他试图将字典转换为 JSO
  • 可以获取位置,但无法获取航向

    我目前只使用模拟器 但我在 iOS 模拟器上快速使用 CoreLocation 时遇到问题 我得到此代码打印的位置更新 但从未得到标题 我不想当然 我正在尝试制作一个指南针类型的应用程序 它将显示目标的方位 class CompassVie
  • iOS 防止计时器 UILabel 在数字变化时“晃动”

    我有一个UILabel它以以下格式显示计时器的输出MM ss SS 分 秒 厘秒 但是随着厘秒宽度的变化 它从左向右 摇动 例如 11 比 33 窄 有什么办法可以减轻这种情况吗 我尝试过将其居中 给它固定的宽度 但它们似乎没有帮助 从iO
  • AWS S3 公共对象与私有对象?

    回到 S3 我的存储桶中有图像的 URL 我将在我的应用程序中呈现这些图像 但它们被设置为私有 当我尝试单击该链接时 它显示 访问被拒绝 当我将链接的设置更改为公共时 它会通过 但是我读到公共访问并不是最安全的事情 所以这本质上是一个由两部
  • SwiftUI:状态栏颜色

    有没有办法将 SwiftUI 视图的状态栏更改为白色 我可能错过了一些简单的东西 但我似乎找不到在 SwiftUI 中将状态栏更改为白色的方法 到目前为止我只看到 statusBar hidden Bool 状态栏文本 色调 前景色可以通过
  • 用于字数计算的 Swift String 中的字数

    我想做一个程序来找出字符串中有多少个单词 用空格 逗号或其他字符分隔 然后把总数加起来 我正在制作一个平均计算器 所以我想要数据总数 然后将所有单词相加 update Xcode 10 2 x Swift 5 或更高版本 使用基础方法enu
  • iOS 中的构建对象文件扩展名是什么?

    当我在项目中构建java对象类时 将创建带有 class扩展名的构建文件 并且人类不可读 快速构建文件怎么样 example car java gt build gt car class 构建后会是什么 car swift gt build
  • 在 Swift 中使用 CommonCrypto 解密时出现问题

    我在一家Swift only加密 解密Extension for String and NSData 并且 crypt 部分的工作基于 Zaph 在链接问题中提供的答案 在 Swift 中使用 CCCrypt CommonCrypt 时出现
  • 在现有 iOS 应用程序中集成 React-native(0.40.0) 后找不到 Yoga/Yoga.h 头文件

    在我的 Swift iOS 应用程序中集成 React Native 后 我无法构建 yoga Yoga h file cannot be found 我已经浏览了文档 查看了react native github页面 检查了类似问题的SO

随机推荐

  • 如何在 Capybara 中使用 ruby​​-debug 和 selenium

    我们让 Capybara 使用 selenium 驱动程序 但是当我尝试在步骤中使用 调试器 时 它不太工作 例如在调试控制台中输入 page 有效 但输入 page body 会挂起 当尝试将调试器与 akephalos 驱动程序一起使用
  • Rails 路由中要测试什么?

    我很好奇人们认为什么是充分 彻底的路线测试 和我一起工作的一个人似乎想要断言every路线在我们的路线文件中 无论多么标准 我觉得这是浪费时间 但也许我错了 而且我没有意识到这有一些价值 在某些情况下 我可以看到路由的一些价值 我们仍然有一
  • 后台大JSON优化解析

    我正在解析类似于的大型 JSON 数据像这样的一个 https mangadex org api manga 153 大约有3000 chapter这里的对象 我只需要那些chapter对象与 lang code gb 大约有 1300 个
  • 作为页面发布到 Facebook 页面墙

    我想使用 PHP 作为页面发布到 facebook 页面墙 我通过下面的链接获得了access token https graph facebook com oauth authorize type user agent client id
  • OpenCL 中的最佳本地/全局工作规模

    我想知道如何在 OpenCL 中为不同设备选择最佳的本地和全局工作大小 AMD NVIDIA INTEL GPU 有什么通用规则吗 我是否应该分析设备的物理构建 多处理器数量 多处理器中的流处理器数量等 这取决于算法 实现吗 因为我看到一些
  • 如何以编程方式将视图控制器嵌入到导航视图控制器中

    我正在尝试将视图控制器嵌入到导航视图控制器中 以便获得导航栏和所有其他内容 例如后退按钮 我想以编程方式完成它 它是这样完成的 example ViewController let myVC UIViewController create
  • Xcode:ld:找不到 -lAFNetworking 的库

    由于这个原因 构建总是失败 关于我可以尝试什么的任何想法 编辑 解决方案是打开 xcworkspace 而不是 xcproject 可能是您在安装 pod 后打开 xcodeproj 文件 关闭项目并打开 xcworkspace 文件
  • 从文件输入中查找java中的最大值

    我是Java新手 我正在尝试编写一个程序 要求用户输入仅包含数字的txt文件的名称 该程序将输出文件中数字的总和 平均值 最大值和最小值 我已经编写了程序的大部分内容 但是我一直在尝试找到值的最大值和最小值 您提供的任何信息都会有所帮助 如
  • 运行 sp_executesql 查询需要参数 @statement

    我不确定如何解决此错误 过程或函数 sp executesql 需要参数 statement 但未提供该参数 对于此查询 DECLARE a INT DECLARE b VARCHAR SET a 1 WHILE a lt 30 BEGIN
  • Python lxml etree.tostring() 返回在 mod_wsgi 上运行的空字符串

    我在 CentOS 6 8 上有 Python 2 7 8 我的服务器是基于 Apache2 WSGI 构建的 我的应用程序应该处理通过 http POST 收到的日期 然后根据从本地 xml 文件获取的 XML 模板创建指令 最后 它必须
  • 如何在C中获取grep的输出[重复]

    这个问题在这里已经有答案了 我正在使用函数 execl 在我的 C 代码中执行 grep 命令 并且我想在我的 C 程序中使用此命令的输出 我该怎么做 您可以使用popen include
  • 如何将调试断点添加到 Visual Studio 2015 中“查找结果”窗口中显示的行

    之前版本的 Visual Studio VS 已回答过此问题 提供的解决方案涉及宏 这些宏在 VS 2015 中不再可用 我可以获得 VS 2015 的解决方案吗 我想在 VS 中进行 查找全部 并在查找匹配的每一行上放置一个调试断点 链接
  • 如何使用新的 YouTube 数据 API (V3) 获取特定频道的已上传视频列表?

    我正在尝试获取所有上传到频道的视频的视频 ID 列表 我还想使用新版本的 YouTube Data API V3 我该怎么做呢 您必须获取上传播放列表 ID 才能上传每个视频 为此 您需要获取频道 ID 从频道 ID 获得播放列表 ID 后
  • 如何更改matplotlib中误差线限制的标记符号?

    只是一个简单的问题 我在其中找不到任何有用的信息plt errorbar文档 https matplotlib org 3 1 1 api as gen matplotlib pyplot errorbar html 我想用误差线绘制值 i
  • mongodb服务器端javascript实际上是客户端?

    我有大量文档 我想提取一些统计数据 需要每 15 分钟定期执行一次 大多数统计数据都是基于文档大小 因此我需要获取文档并计算其大小 我的统计信息的输出只是一行 其中包含一些有关文档大小的统计信息 我没有获取整个集合 只是它的一个子集 所以我
  • SHA 和 AES 加密有什么区别? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 SHA 和 AES 加密有什么区别 SHA 不是加密 它是一种单向哈希函数 AES 高级加密标准 是一种对称加密标准 AES 参考 http en w
  • Spring集成IDE

    我记得在 Spring Tool Suite 中看到过用于设计 Spring Integration 工作流程的调色板 很久以前 但我在 Spring Tool Suite 4 x 中找不到它 有人可以告诉我它是否可以作为单独的附加组件使用
  • 替代 async/await

    在我的应用程序中 我有最新分数列表 有时我必须更新 我有这两个函数可以做到这一点 function handleLastestScoresChange scope newLatestScores getNewLatestScores the
  • OAuth 2.0 OpenID Connect Loopback 和 Keycloak

    我无法从 Loopback 连接到 Keycloak 我一直在尝试使用 keycloak connect 库 https github com keycloak keycloak nodejs connect https github co
  • 使用 Swift 从 NSData 中获取数据

    我正在寻找Swift and NSData成为一场令人沮丧的邪恶婚姻 我发现每次处理这件事时 我都觉得所有所谓的新发现的 Swift 安全性都消失了 崩溃的数量 带有无用的痕迹 没有帮助 所以 我了解到 我可以避免可怕的事情UnsafeMu