智能地从母类实例化子类

时间:2014-06-21 10:58:12

标签: ios objective-c class inheritance initialization

让我们说我有一个motheclass(抽象与否) Item 和两个子类 ItemA et ItemB ,它们都继承自的档案

所有实例都是通过以下方法基于NSDictionary创建的

-(id)initWithJSON:(NSDictionary *)d{

//first instantiate common properties from the motherclass
    if ([super initWithJSON:d]){
        //Do specific stuff for the subclass
    }
    return self;
}

现在让我说我从一个Web服务中获取一个可以同时包含ItemA和A的数组。要创建的项目。

目前我所做的是使用if / then条件来确定我将基于字典内容实例化哪个子类,例如:

 [(NSArray*)data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

            if ([obj[@"kind"] isEqualToString:@"A"])
                [interactions addObject:[[ItemA alloc] initWithJSON:obj]];
            else if ([obj[@"kind"] isEqualToString:@"B"])
                [interactions addObject:[[ItemB alloc] initWithJSON:obj]];
            else
            [interactions addObject:[[Item alloc] initWithJSON:obj]];

        }];

现在我的观点如下:有没有办法只有一行代码 - 默认情况下 - 实例化一个 Item 对象,并根据 ItemA <的种类/ strong>或 ItemB 换句话说,如果在解析的NSDictionary参数中满足某些条件,我可以在母类 Item 的init方法中编写一些代码来实例化一个子类吗?

由于

2 个答案:

答案 0 :(得分:2)

在你的母班上,添加一个这样的便利方法:

 +(instancetype)itemWithJSON:(NSDictionary *)obj {
        id item; 

        if ([obj[@"kind"] isEqualToString:@"A"]) {
            item = [[ItemA alloc] initWithJSON:obj];
        } else if ([obj[@"kind"] isEqualToString:@"B"]) { 
            item = [[ItemB alloc] initWithJSON:obj];
        } else {
            item = [[Item alloc] initWithJSON:obj];
        }

        return item;
 }

然后像这样使用它:

 [(NSArray*)data enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
     [interactions addObject:[Item itemWithJSON:obj]];
 }];

答案 1 :(得分:1)

看看NSClassFromString

伪代码示例:

NSString *className = [NSString stringWithFormat:@"Item%@", obj[@"kind]];
Class metaClass = NSClassFromString(className);

*instance = [[metaClass alloc] initWithJSON:obj];

然后,您将此行为封装在您的母班的静态class factory method中。有关详细信息,请参阅Daij-Djan的答案。