2012-05-23 38 views
1

我的問題是有點奇怪,可以說我有一個類從UITableViewCell繼承調用GenericTableViewCell和一些從GenericTableViewCell繼承的類。 我想能夠傳遞一個參數給GenericTableViewCell初始化方法,它會告訴我GenericTableViewCell的哪個子類應該初始化這個TableViewCell。 繼承人我想到的,但我知道它會失敗,因爲它有一個遞歸循環。初始類作爲子類

@implementation GenericTableViewCell 

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier cellIdentifier: (CellIdentifier *) identifier 
{ 
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 
    if (self) { 
     if ([identifier class] == [FirstIdentifier class]){ 
      self = [[FirstTableViewCell alloc] initWithStyle:style reuseIdentifier:reuseIdentifier]; 
     } 
     /// more else statements to check for other identifier cases 
    } 
    return self; 
} 

@end 

有沒有辦法做到這一點?或者我應該檢查init函數之外的標識符,並由此決定我聲明哪個單元格?

+0

當我從NSObject調用'init'我想它會返回我的NSObject實例,而不是例如NSNumber。這真的很奇怪的事情.. – beryllium

+1

爲什麼你想要這個?知道什麼cellIdentifier發送阿隆g,你可能已經有一些if/else或switch語句來檢查。爲什麼不在此刻初始化正確的表視圖類? –

回答

2

是的,你可以這樣做。這是你有時遇到的稱爲類集羣的模式。如果您不使用ARC,則必須釋放自身的原始值以停止內存泄漏。

但是,我不會這樣做。我會在GenericTableViewCell中創建一個工廠方法。

+(GenericTableViewCell*) cellWithStyle: (UITableViewCellStyle)style 
         reuseIdentifier: (NSString *)reuseIdentifier 
         cellIdentifier: (CellIdentifier *) identifier 
{ 
    GenericTableViewCell* ret = nil; 

    if ([identifier class] == [FirstIdentifier class]) 
    { 
     ret = [[FirstTableViewCell alloc] initWithStyle:style reuseIdentifier:reuseIdentifier]; 
    } 
    else 
    { 
     // .... 
    } 
    return [ret autorelease]; 
} 

您可以通過添加到CellIdentifier的方法消除if聲明並覆蓋它subclasseslike這樣的:

// in CellIdentifier.m 

-(id) classForCell 
{ 
    return [GenericTableViewCell class]; 
} 

// in FirstIdentifier.m 

-(id) classForCell 
{ 
    return [FirstTableViewCell class]; 
} 

那麼你的工廠方法變得

+(GenericTableViewCell*) cellWithStyle: (UITableViewCellStyle)style 
         reuseIdentifier: (NSString *)reuseIdentifier 
         cellIdentifier: (CellIdentifier *) identifier 
{ 
    return [[[[identifier classForCell] alloc] initWithStyle:style 
              reuseIdentifier:reuseIdentifier] autorelease]; 
} 
+0

非常感謝你對我的幫助。我猜想我忘記了工廠模式的壞處。 – Nadavrbn

2

應實現的事情被稱爲類簇模式。在你的情況,你不應該調用一個子類initWithStyle:reuseIdentifier:,而不是在子類初始化:

GenericTableViewCell

- (id)initWithCustomIdentifier:(NSString *identifier) { 
    Class cellClass = NSClassFromString(identifier); 

    if (!cellClass) { 
     cellClass = [MyStandardTableViewCell class]; 
    } 
    self = [[cellClass alloc] init]; 

    return self; 
} 

MyStandardTableViewCell(或GenericTableViewCell任何其他子類:

- (id)init { 
    self = [super initWithStyle:someStyle reuseIdentifier:NSStringFromClass([self class])]; 

    if (!self) return nil; 

    // do extra setup here 
    return self; 
} 
+0

謝謝,這是一個很好的解決方案,但JeremyP的解決方案在我的情況下更加靈活。 – Nadavrbn