【问题标题】:NSXMLParser values not being retainedNSXMLParser 值未保留
【发布时间】:2011-01-17 15:15:20
【问题描述】:

这与我之前的问题类似。我没有得到答案,也许通过改变问题我可能会得到答案。

这是我的解析代码:

-(void) parser:(NSXMLParser *) parser  didStartElement:(NSString *) elementName  
                                          namespaceURI:(NSString *) namespaceURI  
                                         qualifiedName:(NSString *) qName   
                                            attributes:(NSDictionary *) attributeDict 
{
    if ([elementName isEqualToString:kimgurl]
        || [elementName isEqualToString:kone_x]
        || [elementName isEqualToString:kone_y]
        || [elementName isEqualToString:kone_radius]
        || [elementName isEqualToString:ktwo_x]
        || [elementName isEqualToString:ktwo_y]
        || [elementName isEqualToString:ktwo_radius]) 
    {
        elementFound = YES;
        theItems = [[Items alloc] init];
    }
}


- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
                                      namespaceURI:(NSString *)namespaceURI
                                     qualifiedName:(NSString *)qName 
{   
    if([elementName isEqualToString:kimgurl])
    {
        theItems.imageURL = self.currentValue;
        [self.currentValue setString:@""];
    }

    else if([elementName isEqualToString:kone_x])
    {
        theItems.iOne_X = self.currentValue;
        [self.currentValue setString:@""];
    }

    else if([elementName isEqualToString:kone_y])
    {
        theItems.iOne_Y = self.currentValue;
        [self.currentValue setString:@""];
    }

    else if([elementName isEqualToString:kone_radius])
    {
        theItems.iOne_Radius = self.currentValue;
        [self.currentValue setString:@""];
    }

    else if([elementName isEqualToString:ktwo_x])
    {
        theItems.iTwo_X = self.currentValue;
        [self.currentValue setString:@""];
    }

    else if([elementName isEqualToString:ktwo_y])
    {
        theItems.iTwo_Y = self.currentValue;
        [self.currentValue setString:@""];
    }

    else if([elementName isEqualToString:ktwo_radius])
    {
        theItems.iTwo_Radius = self.currentValue;
        [self.currentValue setString:@""];
    }

}

-(void) parserDidEndDocument:(NSXMLParser *)parser 
{   
    NSLog(@"enddocument: %@", theItems.imageURL);
}


-(void)parser:(NSXMLParser *) parser foundCharacters:(NSString *)string 
{
    if (elementFound == YES) {
        if(!currentValue)
        {
            currentValue = [NSMutableString string];
        }

        [currentValue appendString: string];
    }
}

当我到达 parserDidEndDocument. theItems 类为空。

这里是 Items.h

#import <Foundation/Foundation.h>


 @interface Items : NSObject {
     @private
     //parsed data
     NSString *imageURL;
     NSString *iOne_X;
     NSString *iOne_Y;
     NSString *iOne_Radius;
     NSString *iTwo_X;
     NSString *iTwo_Y;
     NSString *iTwo_Radius;
 }

@property (nonatomic, retain) NSString *imageURL;
@property (nonatomic, retain) NSString *iOne_X;
@property (nonatomic, retain) NSString *iOne_Y;
@property (nonatomic, retain) NSString *iOne_Radius;
@property (nonatomic, retain) NSString *iTwo_X;
@property (nonatomic, retain) NSString *iTwo_Y;
@property (nonatomic, retain) NSString *iTwo_Radius;


@end

这里是 Items.m

#import "Items.h"


@implementation Items
@synthesize imageURL;
@synthesize iOne_X;
@synthesize iOne_Y;
@synthesize iOne_Radius;
@synthesize iTwo_X;
@synthesize iTwo_Y;
@synthesize iTwo_Radius;

-(void)dealloc
{
    [imageURL release];
    [iOne_X release];
    [iOne_Y release];
    [iOne_Radius release];
    [iTwo_X release];
    [iTwo_Y release];
    [iTwo_Radius release];  
    [super dealloc];
}
@end

这是我的 RootViewController.h

#import <UIKit/UIKit.h>

@class Items;

@interface RootViewController : UIViewController <NSXMLParserDelegate> {
    NSMutableData *downloadData;
    NSURLConnection *connection;

    BOOL elementFound;
    NSMutableString *currentValue;
    NSMutableDictionary *pictures;

    //---xml parsing---
    NSXMLParser *xmlParser;

    Items *theItems;
    NSMutableArray *aItems;

}

@property (nonatomic, retain) Items *theItems;
@property (nonatomic, retain) NSMutableArray *aItems;
@property (nonatomic, retain) NSMutableString *currentValue;

@property (nonatomic, retain) NSMutableData *downloadData;
@property (nonatomic, retain) NSURLConnection *connection;

@end

xml文件示例

<?xml version="1.0" encoding="utf-8"?>
<data>
    <test>
        <url>url</url>
        <one_x>83</one_x>
        <one_y>187</one_y>
        <one_radius>80</one_radius>
        <two_x>183</two_x>
        <two_y>193</two_y>
        <two_radius>76</two_radius>
    </test>
</data>

【问题讨论】:

  • 如果可能的话,通过正确格式化代码并将其减少到相关部分,您将大大增加获得答案的机会。这很难阅读。
  • 看起来每次启动元素时都会创建一个新的theItems,替换旧的但不保留旧的。所以基本上,你有一个巨大的内存泄漏,当你完成后,theItems 指向最后一个解析元素的数据。我猜这不是你想要的。
  • 我试图格式化块中的代码,但对我来说,似乎相当困难。无论如何,即使我在 viewDidLoad 中创建了 theItems,我也会得到相同的结果。
  • 尝试将项目作为属性访问 - 使用 self.theItems 而不是 theItems
  • 我试过了。 parseDidEndDocument 为空

标签: iphone ios nsxmlparser


【解决方案1】:

看起来有几个潜在的问题。在您的 didStartElement 方法中,您正在为每个元素分配/初始化一个新的 Items 对象并覆盖您以前的元素。也许您可以将 Items init 移动到您的 –parserDidStartDocument: 方法中。当你初始化时,它也应该看起来更像这样:

Items *items = [[Items alloc] init]; self.theItems = 物品; [物品发布];

然后,您将在完成后获得正确的保留计数。

我还建议将您的 NSString @property 声明更改为复制而不是保留。代码:

theItems.imageURL = self.currentValue;
[self.currentValue setString:@""];

...没有按照你的想法做。 theItems.imageURL 将指向您的 NSMutableString ,然后您立即清除可变字符串,这意味着 imageURL 指向一个空的可变字符串。然后在所有其他迭代之后,它们都指向同一个空的 NSMutableString。如果您将 @property 声明更改为复制,那么它会将 imageURL 设置为 self.currentValue 内容的不可变 NSString 副本。

【讨论】:

  • 谢谢。这让我更近了一步。至少我知道我做错了什么。再次感谢您。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-15
  • 1970-01-01
  • 2013-01-28
  • 1970-01-01
相关资源
最近更新 更多