我正在从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的新手......我错过了什么?
答案 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中查看断点以帮助调试此类问题。