Objective c 与来自swift的目标c关联对象存储交互
我正在尝试创建一个实用程序,将闭包添加为uicontrol的事件处理程序。尽管我有几个问题,下面是代码:Objective c 与来自swift的目标c关联对象存储交互,objective-c,swift,Objective C,Swift,我正在尝试创建一个实用程序,将闭包添加为uicontrol的事件处理程序。尽管我有几个问题,下面是代码: public func addCallBack(callback: Void -> Void, forControlEvents events: UIControlEvents) { var optClosureDict = objc_getAssociatedObject(self, &UIControlClosureDictKey) as? Dictionar
public func addCallBack(callback: Void -> Void, forControlEvents events: UIControlEvents)
{
var optClosureDict = objc_getAssociatedObject(self, &UIControlClosureDictKey) as? Dictionary<UInt, Set<ClosureWrapper>>
if optClosureDict == nil {
optClosureDict = Dictionary<UInt, Set<ClosureWrapper>>()
}
var closureDict = optClosureDict!
if closureDict[events.rawValue] == nil {
closureDict[events.rawValue] = Set<ClosureWrapper>()
}
var closures = closureDict[events.rawValue]!
let wrapper = ClosureWrapper(callback:callback)
addTarget(wrapper, action:"invoked", forControlEvents: events)
closures.insert(wrapper)
objc_setAssociatedObject(self, &UIControlClosureDictKey, optClosureDict!, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
var res = objc_getAssociatedObject(self, &UIControlClosureDictKey) as? Dictionary<UInt, Set<ClosureWrapper>>
}
public func addCallBack(回调:Void->Void,forControlEvents事件:UIControlEvents)
{
var optclosredict=objc_getAssociatedObject(self,&UIControlClosureDictKey)as?字典
如果optclosredict==nil{
optclosredict=字典()
}
var closureDict=optClosureDict!
如果closureDict[events.rawValue]==nil{
closureDict[events.rawValue]=Set()
}
var closures=closureDict[events.rawValue]!
let wrapper=closurewapper(回调:回调)
addTarget(包装器,操作:“已调用”,forControlEvents:events)
闭包.插入(包装器)
objc_setAssociatedObject(self,&UIControlClosureDictKey,OptClosRedict!,.objc_ASSOCIATION_RETAIN_Non原子)
var res=objc_getAssociatedObject(self,&UIControlClosureDictKey)as?字典
}
1) 这两个if语句看起来都很难看,我调用了一个返回可选值的API,如果它为nil,我想用一些默认值覆盖它,那么我必须强制将其展开。有没有更惯用的“更快”的方法
2) 另外,当我创建一个closureDict时,它有一个int到闭包的键值对,然后我使用setAssociatedObject存储它,然后我在getAssociatedObject中检索到的内容会返回一个包含0个键值对的字典。发生了什么事?这是一个问题,因为我的closureWrapper没有被保留,而且整个东西都不工作您可以简化行:
var optClosureDict = objc_getAssociatedObject(self, &UIControlClosureDictKey) as? Dictionary<UInt, Set<ClosureWrapper>>
if optClosureDict == nil {
optClosureDict = Dictionary<UInt, Set<ClosureWrapper>>()
}
var closureDict = optClosureDict!
--
此外,以下代码不符合您的预期:
var closures = closureDict[events.rawValue]!
let wrapper = ClosureWrapper(callback:callback)
addTarget(wrapper, action:"invoked", forControlEvents: events)
closures.insert(wrapper)
问题在于Set
是一个struct
,与类不同,它不是一个“引用”类型。因此,var closures=…
行正在创建集的新副本,而不是引用原始副本。因此,您正在更新集合的副本,而不是引用closureDict
中的副本
完成后,您可以更新closureDict
:
var closures = closureDict[events.rawValue]!
let wrapper = ClosureWrapper(callback:callback)
addTarget(wrapper, action:"invoked", forControlEvents: events)
closures.insert(wrapper)
closureDict[events.rawValue] = closures
或者更简单地说,就地更新:
let wrapper = ClosureWrapper(callback:callback)
addTarget(wrapper, action:"invoked", forControlEvents: events)
closureDict[events.rawValue]!.insert(wrapper)
--
因此,这将产生以下替代方案:
func addCallBack(callback: Void -> Void, forControlEvents events: UIControlEvents) {
var closureDict = objc_getAssociatedObject(self, &UIControlClosureDictKey) as? ClosureDict ?? ClosureDict()
if closureDict[events.rawValue] == nil {
closureDict[events.rawValue] = Set<ClosureWrapper>()
}
let wrapper = ClosureWrapper(callback:callback)
addTarget(wrapper, action:"invoked", forControlEvents: events)
closureDict[events.rawValue]!.insert(wrapper)
objc_setAssociatedObject(self, &UIControlClosureDictKey, closureDict, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
func addCallBack(回调:Void->Void,forControlEvents事件:UIControlEvents){
var closureDict=objc_getAssociatedObject(self,&uicontrol closuredictkey)作为?closureDict??closureDict()
如果closureDict[events.rawValue]==nil{
closureDict[events.rawValue]=Set()
}
let wrapper=closurewapper(回调:回调)
addTarget(包装器,操作:“已调用”,forControlEvents:events)
closureDict[events.rawValue]!.insert(包装器)
objc_setAssociatedObject(self,&UIControlClosureDictKey,closureDict,.objc_ASSOCIATION_RETAIN_Non原子)
}
或
func addCallBack(回调:Void->Void,forControlEvents事件:UIControlEvents){
var closureDict=objc_getAssociatedObject(self,&uicontrol closuredictkey)作为?closureDict??closureDict()
var closures=closureDict[events.rawValue]??Set()
let wrapper=closurewapper(回调:回调)
addTarget(包装器,操作:“已调用”,forControlEvents:events)
闭包.插入(包装器)
closureDict[events.rawValue]=闭包
objc_setAssociatedObject(self,&UIControlClosureDictKey,closureDict,.objc_ASSOCIATION_RETAIN_Non原子)
}
谢谢,回答得很好
var closures = closureDict[events.rawValue]!
let wrapper = ClosureWrapper(callback:callback)
addTarget(wrapper, action:"invoked", forControlEvents: events)
closures.insert(wrapper)
closureDict[events.rawValue] = closures
let wrapper = ClosureWrapper(callback:callback)
addTarget(wrapper, action:"invoked", forControlEvents: events)
closureDict[events.rawValue]!.insert(wrapper)
func addCallBack(callback: Void -> Void, forControlEvents events: UIControlEvents) {
var closureDict = objc_getAssociatedObject(self, &UIControlClosureDictKey) as? ClosureDict ?? ClosureDict()
if closureDict[events.rawValue] == nil {
closureDict[events.rawValue] = Set<ClosureWrapper>()
}
let wrapper = ClosureWrapper(callback:callback)
addTarget(wrapper, action:"invoked", forControlEvents: events)
closureDict[events.rawValue]!.insert(wrapper)
objc_setAssociatedObject(self, &UIControlClosureDictKey, closureDict, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
func addCallBack(callback: Void -> Void, forControlEvents events: UIControlEvents) {
var closureDict = objc_getAssociatedObject(self, &UIControlClosureDictKey) as? ClosureDict ?? ClosureDict()
var closures = closureDict[events.rawValue] ?? Set<ClosureWrapper>()
let wrapper = ClosureWrapper(callback:callback)
addTarget(wrapper, action:"invoked", forControlEvents: events)
closures.insert(wrapper)
closureDict[events.rawValue] = closures
objc_setAssociatedObject(self, &UIControlClosureDictKey, closureDict, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}