代码之家  ›  专栏  ›  技术社区  ›  Rakesha Shastri

为什么我不能在通知中传递带有枚举键的字典

  •  1
  • Rakesha Shastri  · 技术社区  · 5 年前

    我试图通过一本字典 enum 作为关键 Notification ( [TestEnum: String] )不幸的是,输入casting字典到 [测试枚举:字符串] 收到通知后失败。

    enum TestEnum {
        case test
    }
    
    class NotificationTest {
    
        var sender: String = "" {
            didSet {
                NotificationCenter.default.post(name: Notification.Name(rawValue: "Test"), object: nil, userInfo: [TestEnum.test: "test"])
            }
        }
    
        init() {
            NotificationCenter.default.addObserver(self, selector: #selector(notificationReceived(_:)), name: Notification.Name(rawValue: "Test"), object: nil)
        }
    
        @objc func notificationReceived(_ notification: Notification) {
            print("Notification Received")
            guard let userInfo = notification.userInfo as? [TestEnum: String] else { return } // Type casting fails here even though userInfo shows a TestEnum key in debugger
            print(userInfo[.test])
        }
    
    }
    
    let test = NotificationTest()
    test.sender = "blah"
    

    但是,如果我使用 rawValue 属于 TestEnum 作为关键,当 notification.userInfo 被铸造成 [String: String] .

    1 回复  |  直到 5 年前
        1
  •  3
  •   Ricky Mo    5 年前

    刚刚看了一下 AnyHashable ,当您在 Hashable (你的枚举) 可任意计算的 ,它被包装在属性中 base 在内部 可任意计算的 . 因此,它不能直接强制转换回枚举。这里使用 reduce 改造 [AnyHashable:Any] [TestEnum:String] :

    @objc func notificationReceived(_ notification: Notification) {
        print("Notification Received")
        guard let userInfo = notification.userInfo?.reduce(into: [TestEnum:String](), { (result, entry) in
            if let key = entry.key.base as? TestEnum
            {
                result[key] = entry.value as? String
            }
        }) else {
            print(notification.userInfo)
            return
        } // Type casting fails here even though userInfo shows a TestEnum key in debugger
        print(userInfo[.test])
    }
    

    因为 可任意计算的 符合 CustomStringConvertible ,可以铸造到 String 直接。