字符串转换为NSURL并存储为属性成功,稍后返回nil

时间:2013-02-12 17:17:58

标签: xml-parsing

我正在从feed解析字符串,将它们转换为URL,并将它们存储为FeedItem的属性。最初,它们已成功转换为URL并存储,但稍后,当我访问该属性时,它是零。

FeedItem.h

@interface FeedItem : NSObject

@property (nonatomic, strong) NSString* author;
@property (nonatomic, strong) NSURL* imageURL;
@property (nonatomic, strong) NSString* datePublished;

@end

Parser.m

- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
 namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict
{
// Custom blog object initialized here
if ([elementName isEqualToString:@"entry"]) {
    self.blogEntry = [[FeedItem alloc] init];
}

// Parse image URL that accompanies some blog entries
self.blogEntry.imageURL = [NSURL URLWithString:[attributeDict objectForKey:@"url"]];
if ([[NSURL URLWithString:[attributeDict objectForKey:@"url"]] isKindOfClass:[NSURL class]]) {
    NSLog( @"converted to a url" );

    if ([self.blogEntry.imageURL isKindOfClass:[NSURL class]]) {
        NSLog(@"property of object is url");
    }else if (!self.blogEntry.imageURL) {
        NSLog(@"url becomes nil");
    }else{
        NSLog(@"property of object is NOT url");
    }
}
}

每次打印时都会打印“转换为网址”和“对象的属性为网址”。但是,稍后在同一个文件中:

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

if([elementName isEqualToString:@"entry"]) {
    // An individual blog has been parsed and a pointer to it is added to the parsedResults array

    if ([self.blogEntry.imageURL isKindOfClass:[NSURL class]]) {
        NSLog( @"URL passed" );
    }else if (!self.blogEntry.imageURL) {
        NSLog( @"is nil" );
    }else{
        NSLog(@"no luck");
    }

    [self.parsedResults  addObject:self.blogEntry];

}
}

每次打印都是“nil”。

以下是正在解析的其中一个网址的示例: URL = 'http://2.bp.blogspot.com/-HlNeYKf6Jyk/URKJ0NzA_kI/AAAAAAAAADY/AAkM6mNITlo/s72-c/Ananya's+Illustration.jpg'

我知道如果某个网址有特殊字符会有问题,但由于它最初是成功的,我认为这不应该是问题。

我是Objective-c的新手......我错过了什么?

3 个答案:

答案 0 :(得分:0)

我的猜测是self.blogEntry正在取消分配。

这一行:

self.blogEntry = [[FeedItem alloc] init];

正在取代self.blogEntry之前的内容。在调用“didEndElement”方法之前,您的解析器是否可能多次调用它?

或者,blogEntry是否strong指定为self?如果没有,它可以在方法创建后在方法结束时解除分配。

答案 1 :(得分:0)

您的以下代码不保证实际创建了blogEntry对象。

// Parse image URL that accompanies some blog entries
self.blogEntry.imageURL = [NSURL URLWithString:[attributeDict objectForKey:@"url"]];
if ([[NSURL URLWithString:[attributeDict objectForKey:@"url"]] isKindOfClass:[NSURL class]]) {
    NSLog( @"converted to a url" );

    if ([self.blogEntry.imageURL isKindOfClass:[NSURL class]]) {
        NSLog(@"property of object is url");
    }else if (!self.blogEntry.imageURL) {
        NSLog(@"url becomes nil");
    }else{
        NSLog(@"property of object is NOT url");
    }
}

只有当start元素为“entry”但您正在该块之外访问它而没有任何检查时,才会创建blogEntry对象。当您尝试设置图像URL时,不保证会创建blogEntry对象。

虽然这并不能解释为什么你的imageURL对象在didStartElement回调中有效而在didEndElement回调中没有效。我只是说这很容易出错。

答案 2 :(得分:0)

parser:didStartElement:namespaceURI:qualifiedName:attributes:方法中,您为每个元素设置了self.blogEntry.imageURL。某些元素不包含url属性,当字典不包含特定键时,它会返回nil - 消除之前存储的任何值。

要克服这个问题,你需要这样的代码:

- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName 
attributes:(NSDictionary *)attributeDict
{
    // Custom blog object initialized here
    if ([elementName isEqualToString:@"entry"]) {
        self.blogEntry = [[FeedItem alloc] init];
    }

    // Only allow the element containing the url we want to effect the value
    // of imageURL through
    if ([elementName isEqualToString:@"media"]) {

        self.blogEntry.imageURL = [NSURL URLWithString:[attributeDict objectForKey:@"url"]];
        if ([[NSURL URLWithString:[attributeDict objectForKey:@"url"]] isKindOfClass:[NSURL class]]) {
            NSLog( @"converted to a url" );

            if ([self.blogEntry.imageURL isKindOfClass:[NSURL class]]) {
                NSLog(@"property of object is url");
            }else if (!self.blogEntry.imageURL) {
                NSLog(@"url becomes nil");
            }else{
                NSLog(@"property of object is NOT url");
            }
        }

    }
}

考虑在Xcode中查看断点以帮助调试此类问题。