我尝试使用关联对象向Timer
的扩展添加属性,但函数objc_setAssociatedObject
始终返回nil
。
Timer is a NSObject所以这应该有用。
代码:
extension Timer {
private struct AssociatedKeys {
static var counterAddress = "counter_address"
}
public var repeatCounter: Int {
get {
return objc_getAssociatedObject(self, AssociatedKeys.counterAddress) as? Int ?? 0
}
set {
objc_setAssociatedObject(self,
AssociatedKeys.counterAddress,
newValue,
.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}
任何想法为什么这不起作用?
更多代码:
@nonobjc public class func new(every interval: TimeInterval, _ block: @escaping (Timer) -> Void) -> Timer {
var timer: Timer!
timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + interval, interval, 0, 0) { _ in
print("timer: \(timer.numberOfRepeats), : \(timer.repeatCounter), : \(timer)")
if timer.numberOfRepeats > 0 {
if timer.repeatCounter > timer.numberOfRepeats {
timer.invalidate()
return
} else {
timer.repeatCounter += 1
}
}
block(timer)
}
return timer
}
所以一些问题是我没有使用相同的计时器对象。 还有一些问题:
static let repeatCounterAddress = "repeat_counter_address"
有时未初始化且字符串值为空。
有时我得到相同的关联值,有时则没有。
答案 0 :(得分:4)
尝试以下(注意&符号):
extension Timer {
private struct AssociatedKeys {
static var counterAddress = "counter_address"
}
public var repeatCounter: Int {
get {
return objc_getAssociatedObject(self, &AssociatedKeys.counterAddress) as? Int ?? 0
}
set {
objc_setAssociatedObject(self,
&AssociatedKeys.counterAddress,
newValue,
.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}
始终确保将相同的地址作为key
参数的值。如果您只使用字符串值,则对于objc_getAssociatedObject
或objc_setAssociatedObject
的每次调用,其原始值可能会有所不同。
您可以使用以下代码进行检查:
func test(_ a: UnsafeRawPointer) {
print("\(a)")
}
let a = "abc"
test(a)
test(a)
test(a)
test(a)
打印
0x00006040004427e0
0x00006040004427e0
0x0000608000052980
0x0000600000055c50
例如,,不同的原始指针被解释为不同的关联对象。