NSMutableArray已填充,但数据以某种方式丢失

时间:2010-10-26 08:38:27

标签: iphone objective-c webservice-client

我开始从viewDidLoad获取数据并使用该数据填充NSMutableArray。但是当我想填充UIPicker时我不能因为该数组中没有更多数据。我怎么会失去那个?请帮忙:(

@synthesize activityIndicator;
@synthesize pckCountries;

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad { 

 countriesList = [[NSMutableArray alloc] initWithCapacity:20]; 
 [self getCountriesList];

 NSLog(@"%@", [countriesList count]);


 [super viewDidLoad];

}

- (void)dealloc {
 [activityIndicator release];
    [xmlParser release];
    //[soapResults release];

    [super dealloc];
}

- (void) getCountriesList{


 NSString *soapMsg = 
 [NSString stringWithFormat:
  @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
  "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
  "<soap:Body>"
  "<getCountries xmlns=\"http://www.smsbug.com/api/\" />"
  "</soap:Body>"
  "</soap:Envelope>"
  ];

 NSURL *url = [NSURL URLWithString: 
      @"http://www.smsbug.com/api/webservice.asmx"];
    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
 NSString *msgLength = [NSString stringWithFormat:@"%d", [soapMsg length]];
 [req addValue:@"text/xml; charset=utf-8" 
forHTTPHeaderField:@"Content-Type"];
    [req addValue:@"http://www.smsbug.com/api/getCountries" 
forHTTPHeaderField:@"SOAPAction"];
    [req addValue:msgLength forHTTPHeaderField:@"Content-Length"];   
    [req setHTTPMethod:@"POST"];
    [req setHTTPBody: [soapMsg dataUsingEncoding:NSUTF8StringEncoding]];
 conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
    if (conn) {
        webData = [[NSMutableData data] retain];


  } 
}

-(void) connection:(NSURLConnection *) connection 
didReceiveResponse:(NSURLResponse *) response {
 [webData setLength: 0];
}

-(void) connection:(NSURLConnection *) connection 
 didReceiveData:(NSData *) data {
 [webData appendData:data];
 NSLog(@"%@", webData);
}

-(void) connection:(NSURLConnection *) connection 
  didFailWithError:(NSError *) error {
 [webData release];    
 [connection release];
}

-(void) connectionDidFinishLoading:(NSURLConnection *) connection {
    NSLog(@"DONE READING WEATHER WEB SERVICE. Received Bytes: %d", [webData length]);
    NSString *theXML = [[NSString alloc] 
                        initWithBytes: [webData mutableBytes] 
                        length:[webData length] 
                        encoding:NSUTF8StringEncoding];
    //---shows the XML to test---
    NSLog(theXML);    

    [theXML release]; 

 // stop activity indicator animation
    [activityIndicator stopAnimating];    


 //-----------------------------------------------------------------
 // start parsing received XML message
 //-----------------------------------------------------------------
 if (xmlParser)
 {
  [xmlParser release];
 }
 xmlParser = [[NSXMLParser alloc] initWithData: webData];
 [xmlParser setDelegate:self]; 
 [xmlParser setShouldResolveExternalEntities:YES];
 [xmlParser parse];

 // clear memory
    [connection release];
    [webData release];
}

-(void) parser:(NSXMLParser *) parser 
didStartElement:(NSString *) elementName 
  namespaceURI:(NSString *) namespaceURI 
 qualifiedName:(NSString *) qName
 attributes:(NSDictionary *) attributeDict {

 //NSLog(elementName);
 if ([elementName isEqualToString:@"Country_Name"])
 {  
  countryFound = YES;
 }
}

-(void)parser:(NSXMLParser *) parser foundCharacters:(NSString *)string
{      

  if([string isEqualToString:@"Data Not Found"])
  {
   errorOccured = YES;
  }
  else if(countryFound == YES)
  {   
   //NSLog(string);
   [countriesList addObject:string];

  }
  else
  { 
   [soapResults appendString: string];
  }     
}

-(void)parser:(NSXMLParser *)parser 
didEndElement:(NSString *)elementName 
 namespaceURI:(NSString *)namespaceURI 
qualifiedName:(NSString *)qName
{
 if(errorOccured == YES)
 { 
  UIAlertView *alert = [[UIAlertView alloc] 
         initWithTitle:@"No Data!"                           
         message:@"Sorry"
         delegate:self  
         cancelButtonTitle:@"OK" 
         otherButtonTitles:nil];
  [alert show];
  [alert release];
  [soapResults setString:@""];  
  errorOccured = FALSE;
 }
 else
 {  
  if ([elementName isEqualToString:@"Country_Name"])
  {   
   countryFound = FALSE;
  }  
 }
}

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
 return 1;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{ 
 return countriesList.count;
}

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
 return [countriesList objectAtIndex:row];
}

1 个答案:

答案 0 :(得分:1)

  1. [super viewDidLoad]应该是viewDidLoad方法中的第一个调用。
  2. 存在泄漏 - 您应该在dealloc方法中调用[countriesList release]
  3. NSURLRequest是异步的。和NSXMLParser一样。因此,在下载/解析完成之前,将调用所有选择器委托方法。因此,在所有委托方法中,您应该检查countriesList是否等于nil
  4. 解析完成后(实现parserDidEndDocument:方法接收此消息),您应该明确调用[picker reloadAllComponents]