NSDateクラスの内容を任意の書式で文字列化したいとき、毎度毎度NSDateFormatterクラスを通すのはしんどいです。
かと言って、カテゴリで新たにメソッドを実装しても、毎度毎度それを呼び出すのは正直面倒いです。これはひどい。
NSObjectクラスは、文字列化されるときこっそりとdescription
メソッドを呼び出します。
MethodSwizzlingでそれを差し替えてやれば、デフォルトの書式を変えられそう。
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
int main(int argc, char *argv[]) {
@autoreleasepool {
NSLog(@"%@", [NSDate distantFuture]); // 4001-01-01 00:00:00 +0000
Class nsdate = [NSDate class];
// と言いつつ今回差し替えるのは`descriptionWithLocale:`
// NSDateは他に`description`と`descriptionWithCalendarFormat:timeZone:locale:`がある
SEL name = @selector(descriptionWithLocale:);
// 新しい`descriptionWithLocale:`メソッド、Blocksの第一引数が`self`の代わりになる
IMP description = imp_implementationWithBlock(^NSString*(id obj, id locale) {
NSDateFormatter* format = [[NSDateFormatter alloc] init];
[format setDateFormat:@"yyyy/MM/dd HH:mm:ss"];
return [format stringFromDate:obj];
});
class_replaceMethod(nsdate, name, description,
method_getTypeEncoding(class_getInstanceMethod(nsdate, name)));
NSLog(@"%@", [NSDate distantFuture]); // 4001/01/01 09:00:00
return 0;
}
}
実用性は投げ捨てるもの。
BlockからSelector(メソッド)を作る - Qiita
Methodの処理を差し替える - MethodSwizzling - Qiita
NSDate Class Reference - Mac Developer Library