我有这段代码。
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
if ([elementName isEqualToString:@"stat"]) {
currentKey = [attributeDict objectForKey:@"name"];
currentValue = [[[NSMutableString alloc] init] autorelease];
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
[currentValue appendFormat:string];
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([currentKey isEqualToString:@"url"])
self.urlToServerLog = currentValue;
}
和头文件
@interface HDEAppDelegate : NSObject <NSApplicationDelegate, NSXMLParserDelegate> {
@private
NSWindow *window;
NSString* scratchFolder;
NSMutableString *urlToServerLog;
NSString *currentKey;
NSMutableString *currentValue;
}
@property (assign) IBOutlet NSWindow *window;
@property (assign) IBOutlet NSTextField *output;
@property (assign) IBOutlet NSTextField *matchID;
@property (retain) NSString *scratchFolder;
@property (retain) NSMutableString *urlToServerLog;
-(IBAction) ParserButton:(id)sender;
-(NSFileWrapper*)unzip:(NSData*)zipData;
@end
这里的问题是urlToServerLog/currentValue处的对象被删除。
我找到了一个解决方案是复制对象,但我原来的解决方案仍然有效。为什么在这种情况下不保留工作?
顺便说一句:scratchFolder也与autorelease对象一起使用,它运行得很好。(以完全相同的方式使用,从NSString(autorelease(返回并分配给scratchFolder。
在-parser:didStartElement:namespaceURI:qualifiedName:attributes:
中,分配一个新字符串并自动释放它:
currentValue = [[[NSMutableString alloc] init] autorelease];
这意味着当相应的自动释放池耗尽时,这个字符串将被释放。一般来说,如果一个对象在方法执行完毕后需要保持活动状态,则需要拥有它。在您的情况下,此时不要自动释放它(记住在不再需要它时释放它(,或者将currentValue
设为retain
属性并使用self.currentValue = …
。
需要考虑的另一点是:您可能希望将urlToServerLog
设置为copy
属性,而不是retain
属性,因为currentValue
是一个可变字符串,在执行XML解析器时会发生更改。如果使用retain
,则urlToServerLog
属性也将发生更改,因为它指向相同的可变字符串。通过将属性更改为copy
,可以有效地复制currentValue
——对currentValue
的任何进一步更改都不会影响该属性。
didStartElement:
结束时释放currentValue
。我假设currentValue
是一个类变量?将currentValue
分配给urlToServerLog
后,您看到它的值是多少?