我该如何调用
print(NSDate())
而不是接收通常的响应,而是在名为 getString()
的函数中获取我拥有的响应,该函数是NSDate
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)
}
}
请注意,我不想只使用:
NSDate().getString()
我想覆盖此类的原始
description
。
更新:
因此,一切看起来唯一的选择都是方法重排,如果甚至可能。
有人对赏金感兴趣吗?
小心
我这样做只是为了个人成长并了解概念,不打算在这种情况下使用它发布应用程序,甚至现在都不确定我可以在什么情况下使用它。
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)
确定这是一个可怕的、坏的、不好的、可怕的想法。但是你去吧:
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
可以定义自己的打印版本:
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)
您可以使用相同的类名在模块中定义 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 这是被覆盖的
请注意,这实际上覆盖了描述变量,而不仅仅是欺骗打印函数。
根据定义,扩展可以添加功能,但不能覆盖它们。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)
}
}