2016-03-12 37 views
1

在這個例子中使用自省是否正確的做法?在這個例子中使用自省是否正確的做法?

我在UITableView數據源方法tableView:cellForRowAtIndexPath:,我正在檢查數據源對象的類型,以便決定使用哪個子類的哪個UITableViewCell

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    .... 
     id object = [[self getDataSource:tableView] objectAtIndex:[indexPath section]]; 

     if ([object isKindOfClass:[NSString class]] || 
      cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 


     } else if ([object isMemberOfClass:[NSNumber class]]) { 
      cell = [[[CMAutocompleteTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier andAutocompleteTextField:object] autorelease]; 


     } else if ([object isMemberOfClass:[NSDate class]]) { 
      cell = [[[CMDateTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier andTextView:object] autorelease]; 

     } else { 
       cell = [[[CMAutocompleteTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier andAutocompleteTextField:field] autorelease]; 

      } 
    return cell; 
} 
+4

通過在所有單元上使用相同的重用標識符,您將破壞細胞回收,或者當您使用deque時只獲取錯誤類型的單元。每種單元類型都需要一個唯一的標識 –

+2

懷舊--' autorelease' :) –

回答

2

它在技術上沒問題(喬希指出改爲isMemberOfClass:)。

這是值得商榷的,如果它是很好的風格。同一個tableview是否真的顯示了彼此相鄰的不同類的項目?如果有幾個tableview,使用單獨的方法/代表可能更合適。

此外,我認爲你可以改進你的方法命名。 getDataSource不鼓勵 - 「get」具有相當特殊的含義,很少使用(例如,在,NSData)。你也想擺脫「和」,這只是噪音。

最後,有沒有什麼理由今天不用切換到ARC?

+0

是的,它是相同的tableView。關於ARC:如果您擁有一個擁有大量手動內存管理代碼的龐大項目,該怎麼辦?如果我切換到ARC,是否需要更改所有舊代碼? – aneuryzm

+1

雖然您可以從僅使用ARC的新代碼開始,但老感冒的過渡非常值得。如果你沒有做任何奇特的事情,Xcode的轉換工具將(幾乎)完全適合你。儘管我認爲自己在手動內存管理方面非常擅長,但我從來沒有回頭看過。它減少了代碼的大小和噪音,消除了錯誤的機會,我懷疑編譯器的代碼甚至可以更好地優化。做吧! :) – Eiko

4

我看不出有任何理由不檢查數據對象的類,但你應該使用isKindOfClass:而非isMemberOfClass:

後者檢查與接收器類的完全匹配,你不會用你得到的數據類獲得;他們都是class clusters。例如,您所擁有的任何NSString實際上將是__NSCFString。同樣適用於NSDateNSNumber

另外,您應該使用ARC。