今天在開發過程中用到了UITableView,在對cell進行設置的時候,我發現對UITableViewCell的重用設置的方法有如下兩種,剛開始我也不太清楚這兩種之間有什麼區別。直到我在使用方法二進行重用的時候,具體實現代碼如下,其中CJMeetingReplyBasicCell是我自定義的UIT ...
今天在開發過程中用到了UITableView,在對cell進行設置的時候,我發現對UITableViewCell的重用設置的方法有如下兩種,剛開始我也不太清楚這兩種之間有什麼區別。直到我在使用方法二進行重用的時候,具體實現代碼如下,其中CJMeetingReplyBasicCell是我自定義的UITableViewCell類型,但是在運行的時候每次都在調用 CJMeetingReplyBasicCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BasicCell" forIndexPath:indexPath]; 時崩潰,通過查找各種原因,確定不是自己代碼的問題之後,開始瞭解這兩種重用方法的區別。那麼,這兩種重用UITableViewCell的方法之間到底有什麼區別呢?
//方法一 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; //方法二 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { MeetingReplyBasicCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BasicCell" forIndexPath:indexPath]; if (!cell) { cell = [[MeetingReplyBasicCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"BasicCell"]; } return cell; }
一 官網文檔解釋
首先我們看一下在iOS源碼的UITableView.h中對兩者的解釋如下,我們可以看到方法二是在iOS 6.0中開始推出的新方法,在對方法二的解釋中,我們註意標紅的部分的意思是假設我們已經註冊了標識符,這裡我們猜測可能是我們需要對標識符進行註冊。
//UITableView.h - (nullable __kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier; // Used by the delegate to acquire an already allocated cell, in lieu of allocating a new one. - (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0); // newer dequeue method guarantees a cell is returned and resized properly, assuming identifier is registered
接下來我們找到官方文檔,https://developer.apple.com/documentation/uikit/uitableview/1614878-dequeuereusablecellwithidentifie?language=objc,官方文檔對方法二的解釋有兩點需要註意,第一個是返回值的地方如下圖,這裡說道該方法總是返回一個有效的UITableViewCell,這是與方法一不同的地方之一。
第二個需要註意的地方是,在該頁面下麵有一個Important的提示如下圖,該提示就說明瞭方法二的正確使用方法。這裡解釋說要先進行註冊我們自定義或者通過nib的類和標識符,然後再使用方法二進行重用。所以現在我們崩潰的原因就已經明確了,問題就出在沒有進行先註冊我們自定義的類和標識符。
二 常規使用方法
對於這兩種方法的常規使用方法,下麵進行總結一下。
首先,對於方法一,使用方法很簡單,無需進行其他的定義和註冊,代碼如下。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { MeetingReplyBasicCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BasicCell"]; if (!cell) { cell = [[MeetingReplyBasicCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"BasicCell"]; } return cell; }
接下來,我們簡單使用方法二進行重用,具體步驟代碼如下。
//首先,我們再tableview進行配置的時候需要註冊我們已定義的cell類和重用標識符 self.tableView.backgroundColor = xxxx; [self.tableView registerClass:[MeetingReplyBasicCell class] forCellReuseIdentifier:@"BasicCell"];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { MeetingReplyBasicCell *cell = [tableView dequeueReusableCellWithIdentifier:@"BasicCell" forIndexPath:indexPath]; return cell; }