From 23d2ddbfa767dfd24a3bd37e1e412c97b9896250 Mon Sep 17 00:00:00 2001 From: ly <6david9@163.com> Date: Tue, 10 Dec 2013 21:21:08 +0800 Subject: [PATCH] refactor --- Classes/MultibyteDescription.m | 317 +++++++++++++++++++-------------- 1 file changed, 185 insertions(+), 132 deletions(-) diff --git a/Classes/MultibyteDescription.m b/Classes/MultibyteDescription.m index 7f27d81..63c13fd 100644 --- a/Classes/MultibyteDescription.m +++ b/Classes/MultibyteDescription.m @@ -9,161 +9,214 @@ #import "MultibyteDescription.h" #import +#define MDINDENT 3 + @implementation MultibyteDescription -// -// Great ideas from @yusuga: http://qiita.com/items/85437eba2623f6ffbdbd (in Japanese) -// + (void)install { - Class c; - IMP imp; - SEL sel; + [self hackNSArray]; + [self hackNSDictionary]; + [self hackNSSet]; + [self hackNSOrderedSet]; + [self hackNSDate]; +} + ++ (void)hackNSArray +{ + Method sourceMethod1 = class_getInstanceMethod([NSArray class], @selector(descriptionWithLocale:)); + Method targetMethod1 = class_getInstanceMethod([self class], @selector(mdNSArrayDescriptionWithLocale:)); + method_exchangeImplementations(sourceMethod1, targetMethod1); - //------------------------------ - // NSArray - //------------------------------ - c = [NSArray class]; + Method sourceMethod2 = class_getInstanceMethod([NSArray class], @selector(descriptionWithLocale:indent:)); + Method targetMethod2 = class_getInstanceMethod([self class], @selector(mdNSArrayDescriptionWithLocale:indent:)); + method_exchangeImplementations(sourceMethod2, targetMethod2); +} + ++ (void)hackNSDictionary +{ + Method sourceMethod1 = class_getInstanceMethod([NSDictionary class], @selector(descriptionWithLocale:)); + Method targetMethod1 = class_getInstanceMethod([self class], @selector(mdNSDictionaryDescriptionWithLocale:)); + method_exchangeImplementations(sourceMethod1, targetMethod1); - // descriptionWithLocale: - imp = imp_implementationWithBlock(^NSString*(NSArray *arr, id locale) { - NSMutableString *mStr = [NSMutableString stringWithString:@"(\n"]; - [arr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){ - if ([obj isKindOfClass:[NSArray class]] || [obj isKindOfClass:[NSDictionary class]]) { - [mStr appendFormat:@"%@,\n", [obj descriptionWithLocale:locale indent:2]]; + Method sourceMethod2 = class_getInstanceMethod([NSDictionary class], @selector(descriptionWithLocale:indent:)); + Method targetMethod2 = class_getInstanceMethod([self class], @selector(mdNSDictionaryDescriptionWithLocale:indent:)); + method_exchangeImplementations(sourceMethod2, targetMethod2); +} + ++ (void)hackNSSet +{ + Method sourceMethod1 = class_getInstanceMethod([NSSet class], @selector(descriptionWithLocale:)); + Method targetMethod1 = class_getInstanceMethod([self class], @selector(mdNSSetDescriptionWithLocale:)); + method_exchangeImplementations(sourceMethod1, targetMethod1); +} + ++ (void)hackNSOrderedSet +{ + Method sourceMethod1 = class_getInstanceMethod([NSOrderedSet class], @selector(descriptionWithLocale:)); + Method targetMethod1 = class_getInstanceMethod([self class], @selector(mdNSOrderedSetDescriptionWithLocale:)); + method_exchangeImplementations(sourceMethod1, targetMethod1); +} + ++ (void)hackNSDate +{ + Method sourceMethod1 = class_getInstanceMethod([NSDate class], @selector(descriptionWithLocale:)); + Method targetMethod1 = class_getInstanceMethod([self class], @selector(mdNSDateDescriptionWithLocale:)); + method_exchangeImplementations(sourceMethod1, targetMethod1); +} + + +#pragma mark - + +NSString *spaceWithLength(NSUInteger length) +{ + // 添加空格 + NSMutableString *indentStr = [[NSMutableString alloc] initWithCapacity:length]; + for(NSInteger i = 0; i < length; i++) + { + [indentStr appendString:@" "]; + } + return indentStr; +} + +- (NSString *)mdNSArrayDescriptionWithLocale:(NSLocale *)locale +{ + NSArray *arr = (NSArray *)self; + NSMutableString *str = [NSMutableString stringWithFormat:@"[\n"]; + + NSInteger count = [arr count]; + for(NSInteger i = 0; i < count; i++) + { + id obj = arr[i]; + + if ([obj respondsToSelector:@selector(descriptionWithLocale:indent:)]) + { + [str appendFormat:@"%@%@\n", spaceWithLength(MDINDENT), + [obj descriptionWithLocale:[NSLocale systemLocale] indent:MDINDENT]]; + } + else + { + if (i!=(count-1)) { + [str appendFormat:@"%@\"%@\",\n", spaceWithLength(MDINDENT),[obj description]]; } else { - [mStr appendFormat:@" %@", [obj description]]; - if (idx == [arr count] - 1) { - [mStr appendString:@"\n"]; - } else { - [mStr appendString:@",\n"]; - } + [str appendFormat:@"%@\"%@\"\n", spaceWithLength(MDINDENT), [obj description]]; } - }]; - [mStr appendString:@")"]; - return mStr; - }); - sel = @selector(descriptionWithLocale:); - class_replaceMethod(c, sel, imp, method_getTypeEncoding(class_getInstanceMethod(c, sel))); + } + } + [str appendFormat:@"]"]; + return str; +} + +- (NSString *)mdNSArrayDescriptionWithLocale:(NSLocale *)locale indent:(NSUInteger)indent +{ + NSArray *arr = (NSArray *)self; - // descriptionWithLocale:indent: - imp = imp_implementationWithBlock(^NSString*(NSArray *arr, id locale, NSUInteger indent) { - NSMutableString *mStr = [NSMutableString string]; - for (int i = 0; i < indent; i++) { - [mStr appendString:@" "]; + NSMutableString *str = [NSMutableString stringWithFormat:@"[\n"]; + NSInteger count = [arr count]; + for(NSInteger i = 0; i < count; i++) + { + id obj = arr[i]; + + if ([obj respondsToSelector:@selector(descriptionWithLocale:indent:)]) + { + [str appendFormat:@"%@%@\n", spaceWithLength(indent+MDINDENT), [obj descriptionWithLocale:[NSLocale systemLocale] indent:indent+MDINDENT]]; } - [mStr appendString:@"(\n"]; - [arr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){ - if ([obj isKindOfClass:[NSArray class]] || [obj isKindOfClass:[NSDictionary class]]) { - [mStr appendFormat:@" %@,\n", [obj descriptionWithLocale:locale indent:indent + 1]]; + else + { + if (i!=(count-1)) { + [str appendFormat:@"%@\"%@\",\n", spaceWithLength(indent+MDINDENT), [obj description]]; } else { - for (int i = 0; i < indent; i++) { - [mStr appendString:@" "]; - } - [mStr appendFormat:@"%@", [obj description]]; - if (idx == [arr count] - 1) { - [mStr appendString:@"\n"]; - } else { - [mStr appendString:@",\n"]; - } + [str appendFormat:@"%@\"%@\"\n", spaceWithLength(indent+MDINDENT), [obj description]]; } - }]; - for (int i = 0; i < indent - 1; i++) { - [mStr appendString:@" "]; } - [mStr appendString:@")"]; - return mStr; - }); - sel = @selector(descriptionWithLocale:indent:); - class_replaceMethod(c, sel, imp, method_getTypeEncoding(class_getInstanceMethod(c, sel))); + } + [str appendFormat:@"%@]", spaceWithLength(indent)]; + - //------------------------------ - // NSDictionary - // (FIXME: improve indentation) - //------------------------------ - c = [NSDictionary class]; + return str; +} + +- (NSString *)mdNSDictionaryDescriptionWithLocale:(NSLocale *)locale +{ + NSDictionary *dict = (NSDictionary *)self; + NSMutableString *str = [NSMutableString stringWithFormat:@"{\n"]; - // descriptionWithLocale: - imp = imp_implementationWithBlock(^NSString*(NSDictionary *dict, id locale) { - NSMutableString *mStr = [NSMutableString stringWithString:@"{\n"]; + NSArray *keys = [dict allKeys]; + NSInteger count = [keys count]; + for(NSInteger i = 0; i < count; i++) + { + id key = keys[i]; + id value = [self valueForKey:key]; + + NSLog(@"%@", [key description]); - [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { - if ([obj isKindOfClass:[NSArray class]] || [obj isKindOfClass:[NSDictionary class]]) { - [mStr appendFormat:@" %@ = %@;\n", key, [obj descriptionWithLocale:locale indent:2]]; + if ([value respondsToSelector:@selector(descriptionWithLocale:indent:)]) + { + [str appendFormat:@"%@%@ :\n%@%@\n", spaceWithLength(MDINDENT), [key description], spaceWithLength(MDINDENT), + [value descriptionWithLocale:[NSLocale systemLocale] indent:MDINDENT]]; + } + else + { + if (i!=(count-1)) { + [str appendFormat:@"%@%@ :\"%@\",\n", spaceWithLength(MDINDENT), [key description], [value description]]; } else { - [mStr appendFormat:@" %@ = %@;\n", key, [obj description]]; + [str appendFormat:@"%@%@ :\"%@\"\n", spaceWithLength(MDINDENT), [key description], [value description]]; } - }]; - [mStr appendString:@"}"]; - return mStr; - }); - sel = @selector(descriptionWithLocale:); - class_replaceMethod(c, sel, imp, method_getTypeEncoding(class_getInstanceMethod(c, sel))); - - // descriptionWithLocale:indent: - imp = imp_implementationWithBlock(^NSString*(NSDictionary *dict, id locale, NSUInteger indent) { - NSMutableString *mStr = [NSMutableString string]; - for (int i = 0; i < indent; i++) { - [mStr appendString:@" "]; } - [mStr appendString:@"{\n"]; + } + [str appendFormat:@"}"]; + return str; +} + +- (NSString *)mdNSDictionaryDescriptionWithLocale:(NSLocale *)local indent:(NSUInteger)indent +{ + NSDictionary *dict = (NSDictionary *)self; + NSMutableString *str = [NSMutableString stringWithFormat:@"{\n"]; + + NSArray *keys = [dict allKeys]; + NSInteger count = [keys count]; + for(NSInteger i = 0; i < count; i++) + { + id key = keys[i]; + id value = [self valueForKey:key]; - [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { - if ([obj isKindOfClass:[NSArray class]] || [obj isKindOfClass:[NSDictionary class]]) { - [mStr appendFormat:@"%@ = %@;\n", key, [obj descriptionWithLocale:locale indent:indent + 1]]; + if ([value respondsToSelector:@selector(descriptionWithLocale:indent:)]) + { + [str appendFormat:@"%@%@\n%@ :%@\n", spaceWithLength(MDINDENT+indent), [key description], spaceWithLength(MDINDENT), + [value descriptionWithLocale:[NSLocale systemLocale] indent:MDINDENT+indent]]; + } + else + { + if (i!=(count-1)) { + [str appendFormat:@"%@%@ :\"%@\",\n", spaceWithLength(MDINDENT+indent), [key description], [value description]]; } else { - for (int i = 0; i < indent; i++) { - [mStr appendString:@" "]; - } - [mStr appendFormat:@"%@ = %@;\n", key, [obj description]]; + [str appendFormat:@"%@%@ :\"%@\"\n", spaceWithLength(MDINDENT+indent), [key description], [value description]]; } - }]; - for (int i = 0; i < indent - 1; i++) { - [mStr appendString:@" "]; } - [mStr appendString:@"}"]; - return mStr; - }); - sel = @selector(descriptionWithLocale:indent:); - class_replaceMethod(c, sel, imp, method_getTypeEncoding(class_getInstanceMethod(c, sel))); - - //------------------------------ - // NSSet - //------------------------------ - c = [NSSet class]; - - // descriptionWithLocale: - imp = imp_implementationWithBlock(^NSString*(NSSet* set, id locale) { - return [NSString stringWithFormat:@"{%@}",[[set allObjects] descriptionWithLocale:locale]]; - }); - sel = @selector(descriptionWithLocale:); - class_replaceMethod(c, sel, imp, method_getTypeEncoding(class_getInstanceMethod(c, sel))); - - //------------------------------ - // NSOrderedSet - //------------------------------ - c = [NSOrderedSet class]; - - // descriptionWithLocale: - imp = imp_implementationWithBlock(^NSString*(NSOrderedSet* orderedSet, id locale) { - return [NSString stringWithFormat:@"{%@}",[[orderedSet array] descriptionWithLocale:locale]]; - }); - sel = @selector(descriptionWithLocale:); - class_replaceMethod(c, sel, imp, method_getTypeEncoding(class_getInstanceMethod(c, sel))); - - //------------------------------ - // NSDate - //------------------------------ - c = [NSDate class]; - - // descriptionWithLocale: - imp = imp_implementationWithBlock(^NSString*(NSDate* date, id locale) { - return [NSDateFormatter localizedStringFromDate:date - dateStyle:NSDateFormatterMediumStyle - timeStyle:NSDateFormatterMediumStyle]; - }); - sel = @selector(descriptionWithLocale:); - class_replaceMethod(c, sel, imp, method_getTypeEncoding(class_getInstanceMethod(c, sel))); + } + [str appendFormat:@"}"]; + return str; +} + +- (NSString *)mdNSSetDescriptionWithLocale:(NSLocale *)locale +{ + NSSet *set = (NSSet *)self; + return [NSString stringWithFormat:@"{%@}", [[set allObjects] descriptionWithLocale:locale]]; +} + +- (NSString *)mdNSOrderedSetDescriptionWithLocale:(NSLocale *)locale +{ + NSOrderedSet *set = (NSOrderedSet *)self; + NSLog(@"%@", [set array]); + return [NSString stringWithFormat:@"{%@}", [[set array] description]]; +} + +- (NSString *)mdNSDateDescriptionWithLocale:(NSLocale *)locale +{ + NSDate *date = (NSDate *)self; + return [NSDateFormatter localizedStringFromDate:date + dateStyle:NSDateFormatterMediumStyle + timeStyle:NSDateFormatterMediumStyle]; } @end