在我的应用中(仅显示相关代码),我有一个带有属性
的班级Test
var location: CLLocation
我使用
归档它public func encode(with aCoder: NSCoder) {
aCoder.encode(location, forKey: "location")
}
使用
取消归档required convenience public init?(coder aDecoder: NSCoder) {
let unarchivedLocation = aDecoder.decodeObject(forKey: "location") as! CLLocation
self.init(location: unarchivedLocation)
}
使用
完成单元测试func test_archiningUnarchiving() {
// given
let location = CLLocation.init(latitude: 0.0, longitude: 0.0)
let test = Test(location: location)
// when
let data = NSKeyedArchiver.archivedData(withRootObject: test)
let unarchivedTest = NSKeyedUnarchiver.unarchiveObject(with: data) as? Test
// then
XCTAssertEqual(unarchivedTest!.location, location, "location was not correctly unarchived")
}
此测试失败:
XCTAssertEqual failed: ("<+0.00000000,+0.00000000> +/- 0.00m (speed -1.00 mps / course -1.00) @ 1/19/18, 3:30:50 PM Central European Standard Time") is not equal to ("<+0.00000000,+0.00000000> +/- 0.00m (speed -1.00 mps / course -1.00) @ 1/19/18, 3:30:50 PM Central European Standard Time") - location was not correctly unarchived
日志显示原始位置和未归档位置的两倍完全相同的数据 知道什么可能出错了吗?
答案 0 :(得分:2)
问题不在于存档,而在于平等测试。如果您比较两个不同的CLLocation
个实例,即使它们相同,也会始终返回false
。
底线,任何未明确实现NSObject
的{{1}}子类(例如isEqual:
的情况)都会遇到此行为。
Swift提供
CLLocation
和==
运算符的默认实现,并对从===
类派生的对象采用Equatable
协议。NSObject
运算符的默认实现调用==
方法...不应覆盖从Objective-C导入的类型的相等或标识运算符。
并且,Using Swift with Cocoa and Objective-C: Interacting with Objective-C APIs告诉我们:
isEqual:
的默认NSObject
实现只是检查指针是否相等。
就个人而言,我希望isEqual:
子类不会自动继承NSObject
,但它就是它。
最重要的是,除非您知道它已正确实现isEqual:
覆盖,否则不要尝试测试NSObject
子类的相等性。如果您愿意,可以编写自己的方法,例如: isEqual:
(但不是isEqual(to location: CLLocation)
)执行两个isEqual(_:)
对象的成员比较。