如何覆盖NSDate描述? ..Method Swizzling?

时间:2016-02-02 17:15:32

标签: ios swift swift2 nsdate method-swizzling

我该如何致电

print(NSDate()) 

而不是接收通常的响应,获取我在名为getString()的函数中的那个,该函数是extension NSDate的一部分。

  

这是我的扩展名:

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)
    }
}
  

请注意,我不想只使用:

NSDate().getString()
     

我想覆盖此类的原始description

更新

  

所以,一切似乎唯一的选择是 Method Swizzling if   甚至可能

     

对赏金感兴趣的人吗?

HEADS UP

  

我这样做只是为了个人成长并且理解这一点   概念,没有计划在这种情况下使用它运送应用程序,   我现在甚至不确定在什么情况下我可以使用它。

5 个答案:

答案 0 :(得分:8)

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

打印&#39;默认&#39; /原始行为/使用

print(date.description)

如果您担心在扩展程序中使用print,只需将其替换为

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

答案 1 :(得分:3)

我很确定这是一个可怕的,坏的,不好的,可怕的想法。但是你走了:

print(formset.errors)

输出:

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)

答案 2 :(得分:2)

可以定义您自己的打印版本:

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)
    }
}

这两个调用现在都会打印相同的内容:

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

答案 3 :(得分:1)

您可以在模块中使用相同的类名定义NSDate的覆盖。您必须遵循覆盖NSDate的指导原则,这有点单调乏味(但它至少在操场上有效)

编译器应该在范围内使用覆盖而不是基础:

 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 
     }

     required 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())")

打印:2016-03-04 18:16:22 -0500这是Overriden One

请注意,这实际上会覆盖描述变量,而不仅仅是欺骗打印功能。

答案 4 :(得分:-2)

根据定义,扩展可以添加功能但不能覆盖它们。 Souce:The Swift Programming Language - Extensions

您可以做的是实现协议CustomStringConvertible并替换该行为:

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)
  }
}