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

时间:2019-01-14 06:38:36

标签: swift nsnotificationcenter

我尝试传递一个以enum作为键的字典,并将其作为Notification[TestEnum: String])中的键。不幸的是,收到通知后,将字典类型广播到[TestEnum: String]失败。

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 个答案:

答案 0 :(得分:3)

仅查看了AnyHashable的源代码,当您将Hashable(您的枚举)转换为AnyHashable时,它包装在内部的属性baseAnyHashable。因此,它不能直接转换回您的枚举。这里使用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])
}

并且由于AnyHashable符合CustomStringConvertible,因此可以直接将其强制转换为String