具有相似对象的数组的快速枚举

时间:2014-08-03 00:06:08

标签: objective-c for-loop nsmutablearray fast-enumeration

我对使用填充类似对象的数组进行快速枚举感到困惑

假设:

我有1个班级(股票类),它有1个子类外国股票。

股票类别的属性:

@property float purchaseSharePrice,currentSharePrice;
@property int numberOfShares;

ForeignStock的属性

@property float conversionRate;

我将上面的2个实例放入MutableArray中。如何使用快速枚举显示(NSLog)这两个不同的对象?

 int i = 1;
    for (StockHolding *iterate in shelf) {

        if ([iterate isMemberOfClass:[StockHolding class]])
        {

            NSLog(@"============ Properties of Stock Value %i ============",i);
            NSLog(@"purchase price is  %f",iterate.purchaseSharePrice);
            NSLog(@"current price is %f",iterate.currentSharePrice);
            NSLog(@"number of shares bought is %i",iterate.numberOfShares);

            NSLog(@"--------------Total Value & Cost--------------");
            NSLog(@"Value in dollar for this stock is %f",iterate.valueInDollars);
            NSLog(@"Cost in dollar for this stock is %f",iterate.costInDollars);


            i++;
        }
        else{
            for (ForeignStockHolding *iterate1 in shelf) {
                if ([iterate1 isMemberOfClass:[ForeignStockHolding class]]) {
                    NSLog(@"============ Properties of Stock Value %i  ============",i);
                    NSLog(@"purchase price is  %f",iterate1.purchaseSharePrice);
                    NSLog(@"current price is %f",iterate1.currentSharePrice);
                    NSLog(@"number of shares bought is %i",iterate1.numberOfShares);

                    NSLog(@"--------------Total Value, Cost, & Conversion Rate --------------");
                    NSLog(@"Value in dollar for this stock is %f",iterate1.valueInDollars);
                    NSLog(@"Cost in dollar for this stock is %f",iterate1.costInDollars);
                    NSLog(@"Conversion rate for this stock is %f",iterate1.conversionRate);

                    i++;
                }
            }
        }
    }

上面的代码没有解决,ForeignStock NSLogged的输出为每个ForeignStock实例2次(我知道,对于第二次快速枚举的方法是错误的)。

如何构建快速枚举,它可以使每个对象在数组中的类与每个类 - 子类对象有不同的处理方式?

3 个答案:

答案 0 :(得分:1)

这是一种方法:

int i = 1;
for (StockHolding *iterate in shelf) {

    NSLog(@"============ Properties of Stock Value %i ============",i);
    NSLog(@"purchase price is  %f",iterate.purchaseSharePrice);
    NSLog(@"current price is %f",iterate.currentSharePrice);
    NSLog(@"number of shares bought is %i",iterate.numberOfShares);

    if ([iterate isKindOfClass:[ForeignStockHolding class]])
        NSLog(@"--------------Total Value, Cost, & Conversion Rate --------------");
    else
        NSLog(@"--------------Total Value & Cost--------------");

    NSLog(@"Value in dollar for this stock is %f",iterate.valueInDollars);
    NSLog(@"Cost in dollar for this stock is %f",iterate.costInDollars);

    if ([iterate isKindOfClass:[ForeignStockHolding class]])
        NSLog(@"Conversion rate for this stock is %f", ((ForeignStockHolding*)iterate).conversionRate);

    i++;
}

您不希望第二个for循环,您只想根据类调整行为。在测试类时,我建议您测试作为专用子类实例的对象,而不是完全基类。

然而,测试对象的类通常是代码味道。通常最好让一个类定义自己的行为,然后让客户端代码简单地要求对象执行该行为。因此,例如,可以要求对象描述自己。 StockHolding类将生成包含其属性的描述字符串。 ForeignStockHolding类会调用super来获取基本描述,然后使用它添加的属性添加到它。

答案 1 :(得分:1)

根据isMemberOfClass:调用的结果决定做什么通常表明您错过了继承的机会:在大多数情况下,正确的解决方案是向基类添加方法,并在派生类中覆盖它。

在这种特定情况下,请考虑覆盖从description继承的名为NSObject的现有方法。 StockHoldingForeignStockHolding都应提供实施:

// This implementation goes in StockHolding
-(NSString*)description {
    return [NSString stringWithFormat:@"purchase price is  %f\n"
        "current price is %f\n"
        "number of shares bought is %i\n"
        "--------------Total Value & Cost--------------\n"
        "Value in dollar for this stock is %f\n"
        "Cost in dollar for this stock is %f"
    ,   _purchaseSharePrice
    ,   _currentSharePrice
    ,   _numberOfShares
    ,   _valueInDollars
    ,   _costInDollars
    ];
}
// This implementation goes into ForeignStockHolding
-(NSString*)description {
    return [NSString stringWithFormat:@"%@\n"
        "Conversion rate for this stock is %f"
    ,   [super description]
    ,   _ conversionRate
    ];
}

有了这两个实现,您可以统一记录所有数据,如下所示:

for (StockHolding *item in shelf) {
    NSLog(@"%@", item);
}

答案 2 :(得分:1)

如果您尝试解决问题以获得调试对象的良好表示,请考虑覆盖类中的-description方法。以下是这两个类的示例:

@implementation StockHolding

- (NSString *)description
{
    NSString *objectDescriptionFormat = 
    @"============ Properties of Stock Value %@ ============\n"
    "purchase price is  %f\n"
    "current price is %f\n"
    "number of shares bought is %i\n"
    "\n"
    "--------------Total Value & Cost--------------\n"
    "Value in dollar for this stock is %f\n"
    "Cost in dollar for this stock is %f\n";

    return [NSString stringWithFormat:objectDescriptionFormat, 
        [super description],
        self.purchaseSharePrice,
        self.currentSharePrice,
        self.numberOfShares,
        self.valueInDollars,
        self.costInDollars];
}

@end


@implementation ForeignStockHolding

- (NSString *)description
{
    NSString *objectDescriptionFormat = 
    @"%@"
    "Conversion rate for this stock is %f\n";

    return [NSString stringWithFormat:objectDescriptionFormat, 
        [super description],
        self.conversionRate];
}

@end

记录对象变得简单,因为您只需记录对象,描述就会打印在控制台上。

for (StockHolding *stockHolding in shelf)
{
    NSLog(@"%@", stockHolding);
}