由于NSNotificationCenter.defaultCenter()。postNotificationName userinfo仅接受包含符合AnyObject协议的数据的词典,因此有人对将结构作为NSNotification的一部分发布有任何建议吗?
我最初的想法是将结构包装在类中-但是首先使用结构是什么呢?
我是否遗漏了某些东西,或者仅仅是将Swift与为目标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
问题是原始的Obj-C方法需要一个NSDictionary,它仅将对象类型作为键和值,这会转换为Swift中的[AnyObject:AnyObject],但NSDictionary喜欢将其键与NSObject中的isEqual:进行比较。协议,因此密钥必须是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
}
除了我们可以做得更好!我们可以为您喜欢的任何结构或值(甚至对象)制作通用包装。
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
那是一个可变的包装器,可以随时通过切换var使其不可变。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句