UItableViewCell的復(fù)用機(jī)制,原理解答

轉(zhuǎn)自:http://www.2cto.com/kf/201207/144337.html

今天在看iphone開發(fā)秘籍的時候尘盼,遇到這個問題,就仔細(xì)的深入了一下烦绳,通過測試卿捎,獲取了一些自認(rèn)為還不錯的結(jié)論,希望對大家在cell復(fù)用方面遇到的一些問題會有所幫助径密。

本篇文章只講原理午阵,對于如果對cell做界面,不深入講述。鑒于我的表達(dá)能力有限底桂,可能會有我自己清楚植袍,但是卻說不清楚的地方,如有問題籽懦,留言給我于个。

UITableView在界面的編程用的甚多,iphone開發(fā)也三月有余了暮顺,每次用到cellForRowAtIndexPath的委托方法的時候厅篓,都是直接copy代碼,自己略加一些界面的修改捶码,對于cell的標(biāo)示符都是static NSString* identifier = @"cell";然后調(diào)用dequeueReusableCellWithIdentifier方法獲取cell贷笛,如果cell為空,再調(diào)用[[[UITableViewCellalloc]initWithStyle方法新創(chuàng)建一個宙项,根本沒有考慮過更深一些的東西乏苦。為了講解清楚,現(xiàn)放上一段代碼尤筐,代碼copy自iphone開發(fā)秘籍汇荐,本人為了講解,略加修改盆繁。以下所有講解均依照此代碼進(jìn)行掀淘,因此,如果您希望能夠透徹的了解cell的復(fù)用機(jī)制油昂,建議實(shí)際運(yùn)行以下革娄,跟著講解,查看效果冕碟。代碼只有tableVIew的委托方法拦惋,因此您需要自己創(chuàng)建工程,把這些委托方法加進(jìn)去安寺。

上文一共四個委托方法厕妖,表明tableView一個section,有32行挑庶,高度為58.關(guān)于tableView的高度那個委托方法的返回的高度值言秸,建議最好自己運(yùn)行程序查看以下,最終達(dá)到一頁的界面顯示8個cell迎捺,第8個cell顯示一半也行举畸,但是不能顯示9和7個cell。我這里之所以為58凳枝,由于(480 - 44)/ 58 為7.5 的樣子抄沮,44為navigationBar的高度,480為屏幕的高度『鲜牵總之,需要達(dá)到的效果是一頁顯示7個多的cell锭环。還有那個icon.png需要自己準(zhǔn)備了聪全,要把它顯示出來。是不是很麻煩呀辅辩?沒辦法难礼,誰讓我們在獲得知識呢,知識總是需要點(diǎn)功夫的玫锋。

[cpp]

- (NSInteger)numberOfSectionsInTableView:(UITableView *)aTableView

{

return 1;

}

- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section

{

return 32;

}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

{

return 58;

}

- (UITableViewCell *)tableView:(UITableView *)tView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

UITableViewCellStyle style;

NSString *cellType;

switch (indexPath.row % 4)

{

case 0:

style = UITableViewCellStyleDefault;

cellType = @"Default Style";

//有標(biāo)題沒有正文(沒有細(xì)節(jié)文字)蛾茉。可選的圖片

break;

case 1:

style = UITableViewCellStyleSubtitle;

cellType = @"Subtitle Style";

//標(biāo)題和正文方式撩鹿,上下排布谦炬。可選的圖片

break;

case 2:

style = UITableViewCellStyleValue1;

cellType = @"Value1 Style";

//左邊文字左對齊节沦,右邊文字右對齊键思。可選的圖片

break;

case 3:

style =UITableViewCellStyleValue2;

cellType =@"Value2 Style";

//左邊文字右對齊甫贯,藍(lán)色吼鳞;右邊文字左對齊,黑色叫搁。沒有圖片

break;

}

static int i = 0;

UITableViewCell *cell = [tView dequeueReusableCellWithIdentifier:cellType];

if (!cell)

{

cell = [[[UITableViewCell alloc] initWithStyle:style reuseIdentifier:cellType] autorelease];

++i;

NSLog(@"cell created %d times", i);

}

if (indexPath.row > 3)

cell.imageView.image = [UIImage imageNamed:@"icon.png"];

cell.textLabel.text = cellType;

cell.detailTextLabel.text = @"Subtitle text";

return cell;

}

首先講解一下復(fù)用隊列:

復(fù)用隊列的元素增加:只有在cell被滑動出界面的時候赔桌,此cell才會被加入到復(fù)用隊列中。每次在創(chuàng)建cell的時候渴逻,程序會首先通過調(diào)用dequeueReusableCellWithIdentifier:cellType方法疾党,到復(fù)用隊列中去尋找標(biāo)示符為“cellType”的cell,如果找不到惨奕,返回nil仿贬,然后程序去通過調(diào)用[[[UITableViewCell alloc] initWithStyle:style reuseIdentifier:cellType] autorelease]來創(chuàng)建標(biāo)示符為“cellType”的cell。

先運(yùn)行一次程序墓贿,不要滑動cell茧泪,查看打印日志,會有打印"cell create 1 times",,,"cell create 8 times"聋袋,一共有8個日志队伟,表明cell創(chuàng)建了8次,這個日志打印是在cellForRowAtIndexPath中的創(chuàng)建cell的時候打印的幽勒。然后慢慢向下(向下的意思嗜侮,實(shí)際上是手向上滑動,讓界面顯示下一個cell,向上與之相反)滑動cell锈颗,到顯示第九個cell的時候顷霹,會看到打印一條日志"cell create 9 times",然后繼續(xù)慢慢向下滑動,會有"cell create 10 times"击吱,直到滑動到第12個cell以后淋淀,cell被創(chuàng)建了12個之后,以后再怎么滑動覆醇,cell都不會被創(chuàng)建了朵纷。也就是說本tableView要完整的工作,一共創(chuàng)建了12個cell永脓。

開始解釋原因了:

第一頁的界面一共需要展示8個cell袍辞,故而cell需要創(chuàng)建8次,每一個cell負(fù)責(zé)自己的數(shù)據(jù)顯示常摧。此8個創(chuàng)建以后搅吁,復(fù)用隊列依然為空(因?yàn)槟愦藭r還沒有滑動cell呢,復(fù)用隊列的元素不會增加)落午。然后在向下滑動顯示出第9個cell的時候似芝,還會調(diào)用cellForRowAtIndexPath方法,在此方法中板甘,它首先到可復(fù)用隊列中去找党瓮,由于此時隊列為空,它創(chuàng)建了一個cell盐类,打印日志寞奸,同時當(dāng)?shù)?個cell滑動出界面之外,第一個cell進(jìn)入到復(fù)用隊列中在跳,隊列中有一個元素枪萄,此元素的表示符為@"Default Style"。然后繼續(xù)向下滑動cell猫妙,開始顯示第10個cell瓷翻,它同樣到復(fù)用隊列中去找,第10個cell的標(biāo)示符為@"Subtitle Style"割坠,但是隊列中唯一的cell的標(biāo)示符為@"Default Style"齐帚,根據(jù)標(biāo)示符尋找,沒有找到彼哼,故而再次創(chuàng)建一個新的cell对妄,同時將滑動出界面的第2個cell進(jìn)入復(fù)用隊列。此時復(fù)用隊列有兩個元素敢朱,標(biāo)示符為@"Default Style"剪菱,@"Subtitle Style"摩瞎。同樣的道理,滑動到第11個cell的時候孝常,第3個cell入隊旗们,第12個cell的時候,第4個cell入隊构灸。此時復(fù)用隊列的元素個數(shù)為四個上渴,標(biāo)示符分別為:@"Default Style",@"Subtitle Style"冻押,@"Value1 Style"驰贷,@"Value2 Style".然后繼續(xù)滑動cell盛嘿,當(dāng)滑動到第13個cell的時候洛巢,它的標(biāo)示符為@"Default Style",它到復(fù)用隊列中去找次兆,可以找到稿茉。故而,這個cell就不會被創(chuàng)建了芥炭,同理漓库,再次向下滑動,以下的所有cell都可以根據(jù)標(biāo)示符找到對應(yīng)的cell园蝠,不會有被創(chuàng)建的渺蒿。在向下滑動的過程中,滑動出去的cell會被入隊彪薛,不過只入隊創(chuàng)建了的cell茂装,也就是說最終隊列中會有12個cell。對于每次取對應(yīng)標(biāo)示符的元素善延,到底取的是哪一個少态?采用的什么策略?這個我不知道易遣,我通過打印查看的是在向下滑動的過程中彼妻,一直順著隊列找,隊列是一個循環(huán)隊列豆茫。向上滑動的時候侨歉,逆著隊列向上找,由于是循環(huán)隊列揩魂,一直在轉(zhuǎn)圈为肮。

如果你仔細(xì)看的話,你會發(fā)現(xiàn)第一個cell本來沒有圖片肤京,為什么一劃下去再次滑動(如果滑動的距離遠(yuǎn)颊艳,一次搞定茅特,如果滑動的距離近,多上下滑動幾次)上來又有圖片了呢棋枕?這個就要思考一個:第一個cell在滑出界面又劃入界面的時候白修,是從復(fù)用隊列拿到的。復(fù)用隊列有12個元素重斑,第1兵睛,5,9還第一個cell有相同的標(biāo)示符窥浪,第1個沒有圖片祖很,第5個和第9個有圖片。當(dāng)用戶復(fù)用的是第一個cell的時候漾脂,它是沒有圖片假颇,當(dāng)用戶復(fù)用第5,9個cell的時候骨稿,它是有圖片的笨鸡。因此,當(dāng)你上下滑動坦冠,查看第一個cell的時候形耗,你會看到它一會有圖片,一會沒有圖片辙浑。這個跟復(fù)用時候的隊列查找規(guī)則有關(guān)激涤。

實(shí)用篇:

說了那么多,全是關(guān)于原理的∨信唬現(xiàn)在說點(diǎn)實(shí)用的倦踢。如果你想在所有的cell中添加一個按鈕,你是應(yīng)該在if中添加佛玄,還是應(yīng)該在if之外添加呢硼一?毫無疑問,應(yīng)該在if中梦抢,如果你是在if的外面添加的般贼,那會導(dǎo)致,你在向下滑動cell的過程中奥吩,取出來的cell本來已經(jīng)帶有button了哼蛆,而你還在addSubview,按鈕越來越多∠己眨或者你可以采用在if外面添加腮介,前提是每次先cell remove掉其所有的子視圖。這樣太消耗cpu端衰,麻煩了叠洗。如果你想一行隔著一行有按鈕和沒有按鈕甘改,你該怎么做呢?稍微思考一下灭抑,這個可是兩種風(fēng)格的cell十艾,故而在滑出界面進(jìn)行重用的時候,它們應(yīng)該屬于不同的標(biāo)示符腾节。于是你在創(chuàng)建cell的時候忘嫉,應(yīng)該去指定兩種標(biāo)示符,創(chuàng)建兩種cell案腺。當(dāng)然庆冕,也許你聰明了,我是不是可以在if之外先remove掉cell的所有子視圖劈榨,然后根據(jù)row % 2 == 0或者访递!=0 來進(jìn)行addSubView:button嗎?答案當(dāng)然是肯定的鞋既,但是這樣還是同樣的問題力九,太消耗cpu了耍铜。平常我們給每一個cell添加了一個button邑闺,肯定要添加事件的。對于不同的button棕兼,響應(yīng)不同的事件陡舅?那么我是不是通過在if語句中給button設(shè)置它的tag標(biāo)記(例如button.tag = indexpath.row)來實(shí)現(xiàn)呢?哈哈伴挚,你應(yīng)該足夠聰明了吧靶衍,當(dāng)然不行。你可以這樣想茎芋,if語句是用來創(chuàng)建的颅眶,它只被執(zhí)行了(例如上面的例子:12次),但是你可能有幾百行的cell田弥,當(dāng)然你的tag也就只有12個了涛酗,明顯不對應(yīng)。像這樣的偷厦,應(yīng)該怎么處理呢商叹?答案是:放在if的外面。你在if外面設(shè)置了tag標(biāo)記只泼,當(dāng)然剖笙,在某一個具體的時間點(diǎn)上,仍然只有12個標(biāo)記请唱,但是這12個標(biāo)記是可變的弥咪,例如當(dāng)前界面顯示第100-111號的cell过蹂,那么此時的button的tag就會是100-111了,仍然是12個按鈕聚至,但是它們會根據(jù)用戶的滑動榴啸,進(jìn)行不同的tag切換,相當(dāng)于擁有了很多個按鈕晚岭。如果你沒有被我說的話給弄暈鸥印,腦袋又足夠清醒的話,你應(yīng)該可以得出以下的結(jié)論:對于界面的定制坦报,放在if中比較好库说,一個cell中只創(chuàng)建一次;對于數(shù)據(jù)的定制片择,放在if外面比較好潜的,對于不同的cell,表示不同的內(nèi)容字管,雖然只有12個cell啰挪,但是cell中存放的數(shù)據(jù)我可以任意的映射。如果你得出了這個結(jié)論嘲叔,那么如果在加上textField,label等等亡呵,你應(yīng)該可以輕松搞定。不僅僅是表面上硫戈,更重要的是锰什,你理解了原理,掌握了機(jī)制丁逝,萬變都不怕汁胆,即使有新的需求,腦袋想想霜幼,或者拿著這篇文章看看嫩码,希望能給你一些啟示。

作者:lipeng08

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末罪既,一起剝皮案震驚了整個濱河市铸题,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌萝衩,老刑警劉巖回挽,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異猩谊,居然都是意外死亡千劈,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門牌捷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來墙牌,“玉大人涡驮,你說我怎么就攤上這事∠脖酰” “怎么了捉捅?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長虽风。 經(jīng)常有香客問我棒口,道長,這世上最難降的妖魔是什么辜膝? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任无牵,我火速辦了婚禮,結(jié)果婚禮上厂抖,老公的妹妹穿的比我還像新娘茎毁。我一直安慰自己,他們只是感情好忱辅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布七蜘。 她就那樣靜靜地躺著,像睡著了一般墙懂。 火紅的嫁衣襯著肌膚如雪橡卤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天垒在,我揣著相機(jī)與錄音蒜魄,去河邊找鬼扔亥。 笑死场躯,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的旅挤。 我是一名探鬼主播踢关,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼粘茄!你這毒婦竟也來了签舞?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤柒瓣,失蹤者是張志新(化名)和其女友劉穎儒搭,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芙贫,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡搂鲫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了磺平。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片魂仍。...
    茶點(diǎn)故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡拐辽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出擦酌,到底是詐尸還是另有隱情俱诸,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布睁搭,位于F島的核電站介袜,受9級特大地震影響遇伞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜渐排,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望可缚。 院中可真熱鬧帘靡,春花似錦描姚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽懂缕。三九已至搪柑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間渊额,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人犯眠。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓地沮,卻偏偏與公主長得像摩疑,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子楷怒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 今天在看iphone開發(fā)秘籍的時候,遇到這個問題,就仔細(xì)的深入了一下逛薇,通過測試,獲取了一些自認(rèn)為還不錯的結(jié)論呢袱,希望...
    Crazy2015閱讀 858評論 0 3
  • 前言 UITableview在iOS中的使用頻率是非常高的.通常,我們只需要通過設(shè)置代理,并且在代理方法table...
    whitekite閱讀 4,542評論 3 3
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件翅敌、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,094評論 4 62
  • 嗨羞福,你好呀。我是茜喵蚯涮,等你很久了治专。 我在腦海里曾無數(shù)次設(shè)想過你的模樣,雖然不知道你是否白凈斯文清俊遭顶。 但按照我一貫...
    茜喵閱讀 5,750評論 55 122
  • 大家晚上好张峰,今天有點(diǎn)遲了,哎呀都不知道寫什么了棒旗。唔喘批,今天下了一整天的雨,現(xiàn)在外面雨還蠻大的,我在聽著雨聲寫日記饶深,也...
    你們是回不去的舊城閱讀 256評論 0 0