iPhone XML解析器不会将对象添加到可变数组

时间:2010-11-26 17:41:59

标签: iphone

问候,

我在将解析器中的对象添加到可变数组时遇到问题。 它工作正常,直到我将MtableArray从AppDelegate移动到ViewController。这是我调用解析器的地方(MutableArray也在此View中):

 NSURL *url = [[NSURL alloc] initWithString:@"http://example.com"];
 NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];

 parser = [[XMLParser alloc] init];

 [xmlParser setDelegate:parser];

 [xmlParser parse];

...这是在解析器内部,应该添加对象:

if([elementName isEqualToString:@"Element"]) {

  [viewController.marray addObject:parsedObj];

  [parsedObj release];
  parsedObj = nil;
  }

marray是在viewController中合成的。解析器做得很好,我试过NSLog,但marray.count总是(null)。请帮忙!!!

5 个答案:

答案 0 :(得分:1)

试试这个,

[viewController.marray addObject:[parsedObj copy]];

答案 1 :(得分:1)

您是否确认过marray属性是非零的?如果它以某种方式未正确设置,则所有插入都将为no-ops,count方法的结果将为nil。

现在您已经发布了更多代码,这一行就是您的问题:

[marray init];

你需要分配/初始化一个新的NSMutableArray;这一行只是将init消息发送给nil。

答案 2 :(得分:0)

你可以发布更多代码吗?

如果您在调用marray时位于视图控制器内,则不必调用viewController.marray,只需marray

根据我的解析经验,一个建议是使用NSMutableDictionary而不是array..so,例如:

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

    currentElement = [elementName copy];

if([elementName isEqualToString:@"item"])
{
    //Clear out story item caches
    item = [[NSMutableDictionary alloc] init];
    currentTitle = [[NSMutableString alloc] init];
    currentAddress = [[NSMutableString alloc] init];
    currentCity = [[NSMutableString alloc] init];
    currentState = [[NSMutableString alloc] init];
    currentZip = [[NSMutableString alloc] init];
    currentId = [[NSMutableString alloc] init];
}

}

然后添加所有内容:

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{

    if([elementName isEqualToString:@"item"])
{
    //Save values to an item, then store that item into the array
    [item setObject:currentTitle forKey:@"title"];
    [item setObject:currentAddress forKey:@"address"];
    [item setObject:currentCity forKey:@"city"];
    [item setObject:currentState forKey:@"state"];
    [item setObject:currentZip forKey:@"zip"];
    [item setObject:currentId forKey:@"id"];

           // venues is the mutable array
    [venues addObject:[item copy]];
    } else {
        return;
    }
}

现在我的可变数组具有我需要的所有元素,我可以用它做各种事情(比如重新加载表格单元格)。上述代码已经过测试并验证为有效。

答案 3 :(得分:0)

以下是一些代码: ViewController.h

#import <UIKit/UIKit.h>

@class XMLParser;

@interface ViewController : UIViewController{

    NSMutableArray *marray;

    XMLParser *parser;
}

@property (nonatomic, retain) NSMutableArray *marray;
@property (nonatomic, retain) XMLParser *parser;

@end

ViewController.m

#

import "ViewController.h"
    #import "ParsedObj.h"
    #import "XMLParser.h"

    @synthesize marray;
    @synthesize parser;

(...)

    -(void)search:(id)sender{

        [marray init];

         NSURL *url = [[NSURL alloc] initWithString:@"http://example.com"];


    NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];

     parser = [[XMLParser alloc] init];

     [xmlParser setDelegate:parser];

     [xmlParser parse];

(...)

    @end

XMLparser.h:

#import <UIKit/UIKit.h>

@class ViewController, ParsedObj;

@interface XMLParser : NSObject <NSXMLParserDelegate>{

    NSMutableString *currentElementValue;

    ViewController *viewController;
    ParsedObj *parsedObj;

}

@end

..和XMLparser.m:

#import "XMLParser.h"
#import "ViewController.h"
#import "ParsedObj.h"

@implementation XMLParser

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

    if([elementName isEqualToString:@"Root"]) {
        //Initialize the array.
        viewController.marray = [[NSMutableArray alloc] init];
    }
    else if([elementName isEqualToString:@"Element"]) {

        //Initialize the hotel.
        parsedObj = [[ParsedObj alloc] init];

        //Extract the attribute here.
        parsedObj.ID = [[attributeDict objectForKey:@"id"] integerValue];
    }
}

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

    if(!currentElementValue) 
        currentElementValue = [[NSMutableString alloc] initWithString:string];
    else
        [currentElementValue appendString:string];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

    if([elementName isEqualToString:@"Root"])
        return;

    //There is nothing to do if we encounter the Books element here.
    //If we encounter the Book element howevere, we want to add the book object to the array
    // and release the object.
    if([elementName isEqualToString:@"Element"]) {

        [accomodationController.marray addObject:parsedObj];

        parsedObj = nil;
    }
    else {
        NSString *cValue=[currentElementValue stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
        [parsedObj setValue:cValue forKey:elementName];
    }

    [currentElementValue release];
    currentElementValue = nil;
}



- (void)dealloc {
    [parsedObj release];
    [currentElementValue release];
    [super dealloc];
}


@end

答案 4 :(得分:0)

我尝试了一种不同的方法,现在我有两种解决方案,并且两者都存在问题。 我有一个XML解析器,它应该首先从NSMutableArray中调用它来添加对象。解析器工作正常,但这是问题所在。 第一种方法:

我在XMLParser.m中更改了NSXMLParser的init方法(mArray用于Mutable Array和):

- (XMLParser *) initXMLParser:(id)sender {
 [super init];
 mArray=(NSMutableArray *)sender; 
 return self;}

实现文件XMLParser.h中的mArray:

@interface XMLParser : NSObject <NSXMLParserDelegate>{
 NSMutableString *currentElementValue; 
 NSMutableArray *mArray;
 Object *aObject;}
-(XMLParser *) initXMLParser:(id)sender;
@end

那么,让我们来看看我们从ViewController.m调用XMLParser的部分:

    mArray = [[NSMutableArray alloc] init];
 NSURL *url = [[NSURL alloc] initWithString:@"http://www.a.com/some.xml"];
 NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
 XMLParser *parser = [[XMLParser alloc] initXMLParser:self.mArray];
 [xmlParser setDelegate:parser];
    [xmlParser parse];

...这里是ViewController.h:

    @class XMLParser;
    @interface AccomodationSecondViewController : UIViewController{ 
    @public NSMutableArray *mArray;}
    @property (nonatomic, retain) NSMutableArray *mArray;

我不确定,因为这是我第一次使用公共对象所以...... 无论如何,这是XMLParser.m中应该添加对象的部分:

    //This is for closing bracket
    if([elementName isEqualToString:@"Element"]) {    
     [mArray addObject:aObject];
     [aObject release];
     aObject=nil;}

因此,我们的想法是在ViewController中公开可变数组mArray并将指针发送到XMLParser。我知道这可能不太自然,但我只想让它发挥作用。

我的另一个想法是: 将ViewController的指针发送到XMLParser并完成剩下的工作。所以,我更改了initXMLParser:

- (XMLParser *) initXMLParser:(id)sender {
    [super init];
    viewController=(ViewController *)sender;    
    return self;}

这是ViewController.m中我调用方法的部分:

XMLParser *parser = [[XMLParser alloc] initXMLParser:self];

然后我添加对象:

[viewController.mArray addObject:aObject];

为什么这不起作用?!!