我在一个.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 数组中显示的内容:
Amazon.ca.Marketplace 应该是添加到 arrayOfPrices 的最后一个条目,但由于某种原因,它出现在可变数组的每个元素中。为什么呢?
答案 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));