【问题标题】:Store vector in NSData in Swift在 Swift 中将向量存储在 NSData 中
【发布时间】:2017-10-13 13:33:04
【问题描述】:

我不明白为什么下面的代码不起作用:

import Foundation
import SpriteKit

var TestVector: CGVector = CGVector(dx: 1, dy: 1)

var Data: Dictionary<String, Any> = ["abc":CGPoint(x: 0, y: 0), "def":1, "ghi":"Try", "jkl":TestVector]


let DataConverted: Data = NSKeyedArchiver.archivedData(withRootObject: Data)

let DataReceived: Dictionary = (NSKeyedUnarchiver.unarchiveObject(with: DataConverted) as! [String : Any])

错误抛出是:错误:执行被中断,原因:信号 SIGABRT。 进程一直停留在中断点,使用“thread return -x”返回表达式求值前的状态。

对于许多不同类型的数据(String、Int、Double 等)一切正常,但不适用于向量

可以通过 NSKeyedArchiver 归档的数据类型是否有限制?

谢谢

J.

附加信息:这将用于 MultipeerConnectivy 数据传输

【问题讨论】:

  • CGPoint 不应该默认不能转换成(NS)Data,所以它不能被存档。 TestVector 也一样。您需要使其符合NSCoder 协议。
  • 谢谢。然而,它适用于 CGPoint。只有 CGVector 类型会引发错误。你能说出如何使 CGPoint 和 CGVector 符合 NSCoder 协议吗?最好的语法是什么?
  • @Larme 你的意思是NSCoding
  • @LeoDabus 是的,NSCoding。对于@jbegood:stackoverflow.com/questions/37980432/…

标签: ios swift nsdata


【解决方案1】:

查看 NSValue,在这种情况下它是完美的。

NSValue(cgVector: TestVector)一样添加它,当你从字典中读回它时,只需像let vector = cgVectorValue.cgVectorValue那样将它作为CGVector取回

在你的情况下,你这样做:

var TestVector: CGVector = CGVector(dx: 1, dy: 1)
let vectorValue = NSValue(cgVector: TestVector)

let pointValue = NSValue(cgPoint:CGPoint(x: 0, y: 0))

var Data: Dictionary<String, Any> = ["abc":pointValue, "def":1, "ghi":"Try", "jkl":vectorValue]

let DataConverted: Data = NSKeyedArchiver.archivedData(withRootObject: Data)

let DataReceived: Dictionary = (NSKeyedUnarchiver.unarchiveObject(with: DataConverted) as! [String : Any])

if let vectorValue = DataReceived["jkl"] as? NSValue {
    let vector = vectorValue.cgRectValue
}

if let pointValue = DataReceived["abc"] as? NSValue {
    let point = vectorValue.cgPointValue
}

Apple 一直在使用它,也许你在收到键盘通知时已经看到它会显示,在 userInfo 字典中你可以使用键盘大小来获取键盘大小

CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size

注意CGRectValue,获取使用NSValue封装的CGRect

来自 Apple 的文档:

NSValue 对象可以保存任何标量类型,例如 int、float 和 char,以及指针、结构和对象 ID 引用。使用此类来处理集合中的此类数据类型(例如 NSArray 和 NSSet)、键值编码以及其他需要 Objective-C 对象的 API。 NSValue 对象始终是不可变的。

更多关于https://developer.apple.com/documentation/foundation/nsvalue

【讨论】:

  • 谢谢,但它不起作用。错误是:由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'*** - [NSKeyedArchiver encodeValueOfObjCType:at:]:此存档器无法编码结构'在“让DataConverted ...”行
  • 我更新了答案,你那里也有一个 CGPoint,你把它包装在 NSValue 中,就像你在上面看到的那样,然后它必须工作
  • 我倾向于同意其他评论创建符合 NSCoding 协议的自定义类...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多