Init类作为子类

时间:2012-05-23 08:57:07

标签: objective-c ios cocoa-touch cocoa

我的问题有点奇怪,假设我有一个继承自UITableViewCell的类,名为GenericTableViewCell,还有一些继承自GenericTableViewCell的类。 我希望能够将参数传递给GenericTableViewCell init方法,该方法将告诉我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函数之外的标识符,然后决定我声明哪个单元格?

2 个答案:

答案 0 :(得分:2)

是的,你可以这样做。这是你有时会遇到的一种称为类集群的模式。如果您不使用ARC,则必须释放self的原始值以阻止内存泄漏。

但是,我不会这样做。我会在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语句,如下所示:

// 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];
}

答案 1 :(得分:2)

你应该实现的东西叫做类集群模式。在你的情况下,你不应该在子类而不是子类'initializer:

中调用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;
}