代码之家  ›  专栏  ›  技术社区  ›  Reinhard Männer

显然,CLLocation对象无法精确存档/取消存档

  •  0
  • Reinhard Männer  · 技术社区  · 8 年前

    在我的应用程序中(仅显示相关代码),我有一个类 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
    

    日志两次显示原始位置和未归档位置的完全相同的数据。
    你知道到底出了什么问题吗??

    1 回复  |  直到 8 年前
        1
  •  2
  •   Rob Md Fahim Faez Abir    8 年前

    问题不在于归档,而在于平等性测试。如果你比较两个不同的 CLLocation 实例,即使它们完全相同,它也将始终返回 false

    底线,任何 NSObject 未显式实现的子类 isEqual: (例如 CL位置 )将体验此行为。

    这个 Using Swift with Cocoa and Objective-C: Interacting with Objective-C APIs 说:

    Swift提供 == === 操作员和采用 Equatable 派生自的对象的协议 NSObject对象 班的默认实现 == 运算符调用 等质量: 方法对于从Objective-C导入的类型,不应重写相等运算符或标识运算符。

    而且 Concepts in Objective-C Programming: Introspection 告诉我们:

    默认值 NSObject对象 实施 等质量: 只需检查指针是否相等。

    我个人希望 NSObject对象 子类没有自动继承 等质量: ,但事实就是这样。

    总之,不要试图测试 NSObject对象 子类,除非您知道它已正确实现 等质量: 推翻如果需要,请编写自己的方法,例如。 isEqual(to location: CLLocation) (但不是 isEqual(_:) )对两个 CL位置 物体。

    推荐文章