Category是我們?cè)谄匠懘a時(shí)玫霎,必然會(huì)使用到的一種技術(shù),它有諸多好處:
- 將一個(gè)很大的類拆分成相對(duì)獨(dú)立的功能類
- 替換原來的函數(shù)
....
例如:
@interface XPMainViewController (AutoLogin)
- (void)autoLogin;
@end
@interface XPMainViewController (SyncConfig)
- (void)syncRemoteConfig;
@end
看起來Category真的非常不錯(cuò)拔创,可以幫我們模塊化
清晰化我們的代碼,但是它真的靠譜嗎富蓄?我們來驗(yàn)證一下剩燥。
首先,我們先創(chuàng)建一個(gè)NSURLSessionTask的Category:
@interface NSURLSessionTask (Test)
- (NSString*)testName;
@end
@implementation NSURLSessionTask (Test)
- (NSString*)testName {
return @"test";
}
@end
Category很簡(jiǎn)單格粪,就是給NSURLSessionTask增加了一個(gè)叫testName的函數(shù)躏吊!
然后我們來調(diào)用一下試試:
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@"http://www.baidu.com"]];
NSLog(@"%@",[task testName]);
代碼寫到這,我們滿懷信心的Commnd+r帐萎,但是令人意想不到的事情發(fā)生了比伏,我們的程序crash了,堆棧顯示為:
**2016-03-06 13:11:13.806 URLSessionTest[2704:94286] -[__NSCFLocalDataTask testName]: unrecognized selector sent to instance 0x7fa25a5f8e10**
呵呵疆导,看堆棧的信息提示赁项,這個(gè)crash引起的原因是:沒有testName函數(shù)啊3憾巍S撇恕!败富!
Oh悔醋,my god!什么玩意兽叮,我不是已經(jīng)使用Category技術(shù)為NSURLSessionTask增加了這個(gè)函數(shù)了嗎芬骄?怎么還是沒有提示無實(shí)現(xiàn)呢猾愿?
等等,我們?cè)僮屑?xì)看看账阻。什么5倜亍!淘太!__NSCFLocalDataTask無testName實(shí)現(xiàn)姻僧!這是什么玩意,我明明代碼寫的是NSURLSessionTask捌涯痢撇贺!怎么回事?冰抢?显熏?WTF
咦,難道NSURLSession返回的不是NSURLSessionTask晒屎??缓升?不得已鼓鲁,log下class、supperclass等等看看港谊。
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@"http://www.baidu.com"]];
NSLog(@"%@", [task class]);
NSLog(@"%@", [task superclass]);
NSLog(@"%@", [[task superclass] superclass]);
NSLog(@"%@", [[[task superclass] superclass] superclass]);
得到結(jié)果:
**2016-03-06 13:11:13.805 URLSessionTest[2704:94286] __NSCFLocalDataTask**
**2016-03-06 13:11:13.806 URLSessionTest[2704:94286] __NSCFLocalSessionTask**
**2016-03-06 13:11:13.806 URLSessionTest[2704:94286] __NSCFURLSessionTask**
**2016-03-06 13:11:13.806 URLSessionTest[2704:94286] NSURLSessionTask**
在iOS9下骇吭,得到這些結(jié)果,并且iOS7下還不是這個(gè)結(jié)果歧寺,WTFT镎!斜筐!
但是好歹原因總算是找到了:NSURLSession的dataTaskWithURL返回的是一個(gè)private class龙致,壓根就不是NSURLSessionTask,它的superClass的superClass的superClass才是NSURLSessionTask顷链!好長(zhǎng)的繼承鏈...
一次意外的debug目代,也獲得了一個(gè)意外的收貨。
其實(shí)Category這個(gè)技術(shù)和這次的crash沒有直接關(guān)系嗤练,??榛了。可以說這是Apple留的坑吧煞抬。