I have tried to do an extension to NSDate. What I wanted is a flag indicating if the NSDate has to be removed later
So I have tried this in playground
//: Playground - noun: a place where people can play
import UIKit
var str = "Hello, playground"
extension NSDate {
private struct RemovalInformation {
static var removed: Bool = false
}
var removed: Bool {
get {
return (objc_getAssociatedObject(self, &RemovalInformation.removed) as! Bool)
}
set(newValue) {
objc_setAssociatedObject(self, &RemovalInformation.removed, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}
}
}
let date = NSDate()
print( "The Date is: \(date)")
if(date.removed == true) {
print ("removed")
}
But line if(date.removed == true)
produces an error I have no clue how to deal with: "EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)"
objc_getAssociatedObject
returns nil
if no object has been associated
to the NSDate
, and then the forced cast as! Bool
crashes.
(It would also crash if an associated object has been set, but its
value is not convertible to Bool
.)
You can make the property optional:
var removed: Bool? {
get {
return objc_getAssociatedObject(self, &RemovalInformation.removed) as? Bool
}
set(newValue) {
objc_setAssociatedObject(self, &RemovalInformation.removed, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}
}
or provide a default value, e.g. using the nil-coalescing operator ??
:
var removed: Bool {
get {
return objc_getAssociatedObject(self, &RemovalInformation.removed) as? Bool ?? false
}
set(newValue) {
objc_setAssociatedObject(self, &RemovalInformation.removed, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}
}
Note that &RemovalInformation.removed
only serves as a memory address
identifying the associated object uniquely. The contents of that
static property and its type is irrelevant and not used at all. In particular, the object association is not "initialized" with the value of that property.