2016-02-02 2 views
3

Как я могу позвонитьКак переопределить описание NSDate? .. Метод 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 этого класса ,

UPDATE:

Таким образом, все выглядит как единственный вариант Метод Swizzling, если даже возможно.

Кто-нибудь заинтересован в щедрости?

HEADS UP

Я делаю это только для личного роста и получить понять концепцию, не собирается грузить приложение, используя его в этом сценарии, даже не уверен, прямо сейчас, в каких сценариях я мог бы использовать его.

+0

Показать ваше расширение 'NSDate() GetString()'.? –

+0

Я не думаю, что это необходимо, я не добавляю ничего, кроме этой функции. Я попробовал переопределить описание var или func, но я получаю сообщение об ошибке, описывающее селектор obj для описания. Тем не менее, я обновлю свой ответ –

+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 

для печати 'по умолчанию'/изначальное поведение/использовать

print(date.description) 

если вы беспокоиться об использовании печатающего просто замените его на

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

Хороший материал. Я никогда не давал Streamable вторую мысль. Замечательно видеть в действии. –

+0

@RobNapier не слишком много информации о и по умолчанию только Character, String и UnicodeScalar соответствуют Streamable. Я нашел Streamable как очень полезный для сериализации JSON ... – user3441734

+0

любые недостатки с такой реализацией? –

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

Это был мой первый attemp, но не работает –

+0

Это не компилируется, и вы не можете заменить/переопределить методы в расширении (того же класса). –

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 
+0

Я делаю это только для личного роста и для понимания концепции, а не для планирования использования приложения, использующего его. Спасибо, я буду проверять его и тестировать в следующий понедельник. –

+1

Усиление факта, что это ужасная идея. :) –

+0

@RobNapier это не такая ужасная идея, но она НЕ доступна для структур, классов non objc и т. Д. Решение существует! Просто выполните протокол Streamable, и вы сделали это. см. мой ответ, пожалуйста. – user3441734

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 Это переопределенный

Обратите внимание, что это фактически переопределяет переменную описания, а не просто обманывает функцию печати.

+0

Это потому, что я доволен :) Нет, на самом деле я имел в виду ответ, который расширил NSDate с помощью writeTo , который делает практически то же самое (т. Е. Относится только к печать) –

+0

Возможно, «трюк» был плохим выбором слова. Я имел в виду, что объем подхода ограничивается «печатью» (или более «выходным») в отличие от фактического переопределения переменной описания, которая была тем, как я чувствовал, что OP был указан. –

+0

Подкласс: как вы переопределяете переменные и функции класса. Расширение - это другая концепция. –

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) 
+0

проблема в том, что она работает ТОЛЬКО, если используется печать только с одним параметром с типом NSDate. попробуйте распечатать (NSDate(), NSDate()) и увидеть результат ... или просто распечатать («now is:», NSDate()) и т. д. – user3441734

+0

yup, но он отвечает на вопрос;) – Casey

Смежные вопросы