¿Cómo anular la descripción de NSDate? .. ¿Metodo Swizzling?

Como puedo llamar

print(NSDate()) 

y en lugar de recibir la respuesta habitual, obtenga el que tengo en una function llamada getString() que es parte de una extension de NSDate .

Aquí está mi extensión:

 extension NSDate { //NSDate to String public func getString() -> String { let dateFormatter = NSDateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ" dateFormatter.locale = NSLocale.currentLocale() return dateFormatter.stringFromDate(self) } } 

Por favor, tenga en count que no quiero simplemente usar:

 NSDate().getString() 

Quiero anular la description original de esta class.

ACTUALIZAR:

Entonces, todo parece ser que la única opción es el Método Swizzling , si es posible .

¿Alguien interesado en la recompensa?

AVISO

Lo estoy haciendo solo para el crecimiento personal y para entender el concepto, no planear enviar una aplicación que lo use en este escenario, ni siquiera seguro ahora en qué escenarios podría usarlo.

 import Foundation extension NSDate: Streamable { public func writeTo<Target : OutputStreamType>(inout target: Target) { let dateFormatter = NSDateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ" dateFormatter.locale = NSLocale.currentLocale() print("without swizzling", dateFormatter.stringFromDate(self), toStream: &target) } } let date = NSDate() print(date) // without swizzling 2016-03-05 00:09:34 +0100 

para imprimir 'default' / original behavior / use

 print(date.description) 

Si le preocupa usar la printing en su extensión, simplemente reemplácela por

 //print("without swizzling", dateFormatter.stringFromDate(self), toStream: &target) let str = dateFormatter.stringFromDate(self) str.writeTo(&target) 

Estoy bastante seguro de que esta es una idea terrible, mala, nada buena, horrible. Pero aquí tienes:

 extension NSDate { private static let dateFormatter = NSDateFormatter() private static var once = dispatch_once_t() static func swizzleDescription() { dispatch_once(&once) { dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ" dateFormatter.locale = NSLocale.currentLocale() let originalMethod = class_getInstanceMethod(self, "description") let replacementMethod = class_getInstanceMethod(self, "description_terribleIdea") method_exchangeImplementations(originalMethod, replacementMethod) } } func description_terribleIdea() -> String { return NSDate.dateFormatter.stringFromDate(self) } } let date = NSDate() print(date) NSDate.swizzleDescription() print(date) 

Salida:

 2016-03-04 22:17:20 +0000 2016-03-04 16:17:20 -0600 

Podría definir su propia versión de printing:

 func print(date: NSDate) { print(date.getString()) } extension NSDate { //NSDate to String public func getString() -> String { let dateFormatter = NSDateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ" dateFormatter.locale = NSLocale.currentLocale() return dateFormatter.stringFromDate(self) } } 

ambas llamadas ahora imprimirán lo mismo:

 let date = NSDate() print(date.getString()) print(date) 

Podría definir una anulación de NSDate en su module con el mismo nombre de class. Tienes que seguir las pautas para anular NSDate, que es un poco tedioso (pero funciona al less en el patio de recreo)

El comstackdor debe usar su anulación en lugar de la de la base cuando está en el scope:

  public class NSDate:Foundation.NSDate { override public var description:String { return getString() } private var dateValue:NSTimeInterval = Foundation.NSDate().timeIntervalSinceReferenceDate override public var timeIntervalSinceReferenceDate:NSTimeInterval { return dateValue } override public init() { super.init() } override public init(timeIntervalSinceReferenceDate ti: NSTimeInterval) { super.init() dateValue = ti } requinetworking public init?(coder aDecoder: NSCoder) { super.init(coder:aDecoder) } //NSDate to String public func getString() -> String { let dateFormatter = NSDateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ" dateFormatter.locale = NSLocale.currentLocale() return dateFormatter.stringFromDate(self) + " This is the Overriden One" } } print("\(NSDate())") 

impresiones: 2016-03-04 18:16:22 -0500 Este es el anulado

Tenga en count que esto realmente anula la variable de descripción y no solo engaña a la function de printing.

Por definición, las extensiones pueden agregar funcionalidades pero no anularlas. Souce: El lenguaje de progtwigción Swift – Extensiones

Lo que puede hacer es implementar el protocolo CustomStringConvertible y replace ese comportamiento:

 extension NSDate : CustomStringConvertible { var description: String { let dateFormatter = NSDateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ" dateFormatter.locale = NSLocale.currentLocale() return dateFormatter.stringFromDate(self) } }