4

我怎么打电话

print(NSDate()) 

而不是接收通常的响应,而是获取我在一个名为的函数中拥有的响应,该函数getString()是 of 的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如果可能的话

有人对赏金感兴趣吗?

小心

我这样做只是为了个人成长和理解这个概念,而不是计划在这种情况下使用它来发布应用程序,甚至现在还不确定我可以在什么情况下使用它。

4

5 回答 5

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

打印“默认”/原始行为/使用

print(date.description)

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

//print("without swizzling", dateFormatter.stringFromDate(self), toStream: &target)
let str = dateFormatter.stringFromDate(self)
str.writeTo(&target)
于 2016-03-04T23:11:08.297 回答
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

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

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 这是被覆盖的

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

于 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 回答