为什么我的类(struct)没有正确添加到NSMutableArray?

时间:2014-08-24 19:20:18

标签: objective-c class ios7 struct nsmutablearray

我在一个.m文件中定义了两(2)个类:

@interface vendorData : NSObject  {  //  <  first class

@public
  NSString *vendor;
  NSString *price;
  NSString *condition;
}
@end
@implementation vendorData

@end
@interface DetailViewController () < UIAlertViewDelegate>

@end

@implementation DetailViewController  //  <--  second (main) class

//  code for the main class follows

我像这样初始化类和NSMutableArray:

NSMutableArray *arrayOfPrices = [[NSMutableArray alloc]initWithCapacity:100];
vendorData *data = [[vendorData alloc] init];

我使用NSScanner填充类数据,然后将vendorData对象放入NSMutableArray中;这就是我填充数据对象的方式:

    NSData *siteHTMLData = [NSData dataWithContentsOfURL: siteUrl];
siteHTMLData = [NSData dataWithContentsOfURL: siteUrl];  //  get past first page ("searching")
NSString *htmlString = [[NSString alloc] initWithData:siteHTMLData encoding:NSUTF8StringEncoding];

//  start the search
NSScanner *scanner = [[NSScanner alloc] initWithString:htmlString];
NSString *priceString, *vendorString, *conditionString;
vendorData *data = [[vendorData alloc]init];

do {
   @try {


        //  find vendor
        [scanner scanUpToString:@"<tr  id=\"" intoString:nil];
        scanner.scanLocation += 9;

        [scanner scanUpToString: @"\r\n" intoString: &vendorString];  //  find end of vendor
        data->vendor = vendorString;

        //  find price
        scanner.scanLocation += 2;
        [scanner scanUpToString:@"<span >$" intoString:nil];  //  find beginning of price
        scanner.scanLocation += 8;
        [scanner scanUpToString: @"</span>" intoString: &priceString];  //  find end of price
        data->price = priceString;
        scanner.scanLocation += 7;
    }

    @catch (NSException *exception)  {
        if([[exception reason] isEqualToString: NSRangeException])
            break;
    }

    // see if vendor/price is already in array; if so ignore it

    NSLog(@"\ndata->vendor: %@,\n->price: %@", data->vendor, data->price);  //  <---------
    [arrayOfPrices addObject:data];  //  add struct to array



} while (([scanner isAtEnd] == NO) || (scanner.scanLocation > htmlString.length));

这是日志的一部分:

  

2014-08-24 11:53:03.154 BookInventoryManager [3741:60b]   data-&gt;供应商:Thriftbooks.comUsed&#34;,    - &gt;价格:1.00   2014-08-24 11:53:03.155 BookInventoryManager [3741:60b]   data-&gt;供应商:ValoreBooksUsed&#34;,    - &gt;价格:0.01   2014-08-24 11:53:03.155 BookInventoryManager [3741:60b]

这是调试器在 arrayOfPrices 数组中显示的内容:

enter image description here

Amazon.ca.Marketplace 应该是添加到 arrayOfPrices 的最后一个条目,但由于某种原因,它出现在可变数组的每个元素中。为什么呢?

2 个答案:

答案 0 :(得分:1)

与大多数问题一样,可能是您的代码中存在错误。这是你第一次想到的,特别是当你做了成千上万人以前做过的事情时:这是你代码中的一个错误。

我们没有所有代码。我们有一行创建vendorData对象。我们没有看到您设置供应商和价格的位置。我们有一行将vendorData对象添加到可变数组,我们看到可变数组包含两次相同的对象。

最明显的解释是您创建一个vendorData对象一次,然后将供应商和价格设置为不同的值,并始终将相同的vendorData对象添加到可变数组中。将对象添加到可变数组会添加对象,而不是它的副本。

答案 1 :(得分:1)

每次想要追加元素时,都应该创建一个新的对象实例。

您可以创建自己的自定义初始化以使其更容易。这是一个例子:

@interface vendorData : NSObject  { 

@public
  NSString *vendor;
  NSString *price;
  NSString *condition;
}
-(id) initWithVendor:(NSString) vendor price:(NSString *)price  condition:(NSString *) condition;
@end

@implementation vendorData
-(id) initWithVendor:(NSString) vendor price:(NSString *)price  condition:(NSString *) condition{
    self = [super init];
    if(self) {
        self.vendor = vendor;
        self.price = price;
        self.condition = condition;
    }
    return(self);
}
@end

以下是填充可变数组的方法:

NSMutableArray *arrayOfPrices = [[NSMutableArray alloc]initWithCapacity:100];
vendorData *data1 = [[vendorData alloc] initWithVendor:@"Amazon" price:@"31.75" condition: nil];
[arrayOfPrices addObject:data1];
vendorData *data2 = [[vendorData alloc] initWithVendor:@"Ebay" price:@"20.00" condition: @"new"];
[arrayOfPrices addObject:data2];  

编辑:感谢您更新帖子,您需要做的就是在do-while循环中移动对象声明:

do {
vendorData *data = [[vendorData alloc]init];
   @try {
         ...

或者如果你想在我的例子中使用自定义init,可以像这样使用它:

do {
   @try {

        //  find vendor
        [scanner scanUpToString:@"<tr  id=\"" intoString:nil];
        scanner.scanLocation += 9;
        [scanner scanUpToString: @"\r\n" intoString: &vendorString];  //  find end of vendor

        //  find price
        scanner.scanLocation += 2;
        [scanner scanUpToString:@"<span >$" intoString:nil];  //  find beginning of price
        scanner.scanLocation += 8;
        [scanner scanUpToString: @"</span>" intoString: &priceString];  //  find end of price
        scanner.scanLocation += 7;
    }

    @catch (NSException *exception)  {
        if([[exception reason] isEqualToString: NSRangeException])
            break;
    }

    // see if vendor/price is already in array; if so ignore it
    vendorData *data = [[vendorData alloc] initWithVendor:vendorString price:priceString condition: nil];
    NSLog(@"\ndata->vendor: %@,\n->price: %@", data->vendor, data->price);  
    [arrayOfPrices addObject:data];  //  add struct to array


} while (([scanner isAtEnd] == NO) || (scanner.scanLocation > htmlString.length));