Dan*_*agh 18 struct nsnotification userinfo swift
由于NSNotificationCenter.defaultCenter().postNotificationName userinfo只接受符合AnyObject协议的数据的字典,有没有人有任何建议如何发布结构作为NSNotification的一部分?
我最初的想法是将结构包装在一个类中 - 但是那么首先使用结构的意义何在.
我是否遗漏了某些内容,或者这只是将Swift与为Objective C构建的API混为一谈的结果?
这是我所描述的一个示范: -
class wrapper: NSObject {
var aStructToWrap: aStruct
init(theStruct: aStruct) {
aStructToWrap = theStruct
super.init()
}
}
struct aStruct {
var aValue: String
}
let aRealStruct = aStruct(aValue: "egg")
NSNotificationCenter.defaultCenter().postNotificationName("aKey", object: nil, userInfo: ["anotherKey": aRealStruct]) // ERR: Extra argument 'userinfo' in call
let wrappedStruct = wrapper(theStruct: aRealStruct)
NSNotificationCenter.defaultCenter().postNotificationName("aKey", object: nil, userInfo: ["anotherKey": wrappedStruct]) // no error
Run Code Online (Sandbox Code Playgroud)
Ric*_*ett 30
问题是原始的Obj-C方法需要一个NSDictionary,它只将对象类型作为键和值,转换为Swift中的[AnyObject:AnyObject],除了NSDictionary喜欢将它的键与isEqual进行比较:它在NSObject中协议,所以密钥必须是一个NSObject(我不知道NSObjectProtocol是否足够,但Apple决定将它变为NSObject).因此,NSDictionary userInfo必须是Swift中的[NSObject:AnyObject],所以你不能在那里放一个结构,我也不相信你可以在Objective-C中.
可悲的是,包装将是必要的.我们可以使用NSValue并产生一些丑陋和低效的东西,但无论如何最好的解决方案是你创建的包装器.
但是,你创建了一个NSObject的子类,这是不需要的,所以你可以抛弃那些代码:)
class Wrapper {
var aStructToWrap: aStruct
init(theStruct: aStruct) {
aStructToWrap = theStruct
}
}
struct aStruct {
var aValue: String
}
Run Code Online (Sandbox Code Playgroud)
除了我们可以做得更好!我们可以为您喜欢的任何结构或值(甚至是对象)创建一个通用包装器.
class Wrapper<T> {
var wrappedValue: T
init(theValue: T) {
wrappedValue = theValue
}
}
struct aStruct {
var aValue: String
}
let aRealStruct = aStruct(aValue: "egg")
let wrappedStruct = Wrapper(theValue: aRealStruct)
NSNotificationCenter.defaultCenter().postNotificationName("aKey", object: nil, userInfo: ["anotherKey": wrappedStruct]) // no error
Run Code Online (Sandbox Code Playgroud)
这是一个可变的包装器,可以通过切换一个let的var来使它变得不可变.