因?yàn)橛泻脦讉€(gè)童鞋問(wèn)過(guò)這個(gè)事了,參考ZXPUnicode:
首先編碼轉(zhuǎn)換的代碼可以是:
- (NSString *)stringByReplaceUnicode:(NSString *)unicodeString
{
NSMutableString *convertedString = [unicodeString mutableCopy];
[convertedString replaceOccurrencesOfString:@"\\U" withString:@"\\u" options:0 range:NSMakeRange(0, convertedString.length)];
CFStringRef transform = CFSTR("Any-Hex/Java");
CFStringTransform((__bridge CFMutableStringRef)convertedString, NULL, transform, YES);
return convertedString;
}
雖然這樣可以隨便做category
手動(dòng)調(diào)用了撵渡,但還是需要引用頭文件渠缕,不方便仰楚。所以需要做Method Swizzling
岔霸,替換掉系統(tǒng)的description相關(guān)方法薛躬,在自定義交換方法中添加如上述代碼類(lèi)似的編碼轉(zhuǎn)換操作,一勞永逸(呆细。?????)型宝。具體可以是對(duì)NSDictionary
、NSArray
以及NSSet
作一個(gè)category
絮爷,在類(lèi)被初始加載調(diào)用load
方法時(shí)做Method Swizzling
:
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
zx_swizzleSelector([self class], @selector(descriptionWithLocale:indent:), @selector(zx_descriptionWithLocale:indent:));
});
}
- (NSString *)zx_descriptionWithLocale:(id)locale indent:(NSUInteger)level
{
return [self stringByReplaceUnicode:[self zx_descriptionWithLocale:locale indent:level]];
}
swizzleSelector
中交換了兩個(gè)方法的實(shí)現(xiàn)趴酣。所以方法中調(diào)用zx_descriptionWithLocale:indent:
其實(shí)是調(diào)用的原生的descriptionWithLocale:indent:
方法。在系統(tǒng)方法返回時(shí)略水,進(jìn)行編碼轉(zhuǎn)換就OK啦(价卤。?????)。
原生的descriptionWithLocale:indent:
方法是這樣獲取描述的: 如果元素是NSString
對(duì)象則直接返回它; 當(dāng)元素響應(yīng)descriptionWithLocale:indent:
方法時(shí)渊涝,調(diào)用方法獲得該元素的字符串描述; 當(dāng)元素響應(yīng)descriptionWithLocale:
方法時(shí)慎璧,調(diào)用方法獲得該元素的字符串描述; 如果上述條件都不符合,就會(huì)調(diào)用該元素的description
方法獲取字符串描述跨释。
原生方法執(zhí)行遍歷子元素的時(shí)候胸私,還是會(huì)調(diào)用descriptionWithLocale:indent:
方法來(lái)獲取子元素的描述,當(dāng)原生方法被調(diào)用時(shí)鳖谈,因方法實(shí)現(xiàn)的交換又會(huì)執(zhí)行自定義的交換方法的代碼岁疼,形成間接遞歸,上述條件符合時(shí)原生方法會(huì)返回正確描述開(kāi)始回歸缆娃,回歸時(shí)依次進(jìn)行編碼轉(zhuǎn)換捷绒。這樣有個(gè)小小的問(wèn)題,就是回歸過(guò)程中已經(jīng)被編碼轉(zhuǎn)換過(guò)的字符串有可能會(huì)被重復(fù)轉(zhuǎn)換好多次贯要。這里我們交換的是descriptionWithLocale:indent:
這一個(gè)原生方法暖侨。如果可以的話(huà),可以只交換原生的description
方法崇渗,然后輸出的時(shí)候調(diào)一下description
(例如你有個(gè)字典dict字逗,這樣打印:NSLog(@"%@", dic.description)
), 這么做只是將系統(tǒng)方法返回的最終描述進(jìn)行了一次編碼轉(zhuǎn)換宅广。ps: 如果你不嫌麻煩的話(huà)葫掉,可以這么用 ?乛?乛? 。跟狱。俭厚。。
補(bǔ)上Method Swizzling代碼:
static inline void zx_swizzleSelector(Class theClass, SEL originalSelector, SEL swizzledSelector)
{
Method originalMethod = class_getInstanceMethod(theClass, originalSelector);
Method swizzledMethod = class_getInstanceMethod(theClass, swizzledSelector);
BOOL didAddMethod =
class_addMethod(theClass,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(theClass,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}