4

How can I call

print(NSDate()) 

and instead of receiving the usual response, obtain the one I have in a function named getString() that is part of an extension of NSDate.

Here's my extension:

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

Please, note that I don't want to just use:

NSDate().getString()

I want to override original description of this class.

UPDATE:

So, everything looks like the only option is Method Swizzling, if even possible.

Anyone interested in the bounty?

HEADS UP

I'm doing this just for personal growth and to get to understand the concept, not planning on shipping an App using it in this scenario, not even sure right now in what scenarios I could be using it.

4

5 に答える 5

3

これはひどい、悪い、良くない、恐ろしい考えだと確信しています。しかし、ここに行きます:

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)

出力:

2016-03-04 22:17:20 +0000
2016-03-04 16:17:20 -0600
于 2016-03-04T22:18:01.433 に答える
2

独自のバージョンの print を定義できます:

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)
于 2016-03-08T07:21:21.773 に答える
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 これは上書きされたものです

これは実際には description 変数をオーバーライドするものであり、印刷機能をだますだけではないことに注意してください。

于 2016-03-04T23:20:32.670 に答える
-2

定義上、拡張機能は機能を追加できますが、オーバーライドすることはできません。ソース: Swift プログラミング言語 - 拡張機能

できることは、プロトコル 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)
  }
}
于 2016-02-02T17:37:24.320 に答える