8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

オブジェクトを文字列化するときの書式を変える

Posted at

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

8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?