retain在Objective-C中是如何工作的?

retain在Objective-C中是如何工作的?,objective-c,properties,retain,Objective C,Properties,Retain,我有这个密码 -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{ if ([elementName isEqualToString:@"stat"]) {

我有这个密码

-(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
@接口HDEAppDelegate:NSObject{
@私人的
NSWindow*窗口;
NSString*scratchFolder;
NSMutableString*urlToServerLog;
NSString*currentKey;
NSMutableString*当前值;
}
@属性(分配)窗口*窗口;
@属性(分配)IBNStextField*输出;
@属性(分配)IBMOutlet NSTextField*匹配ID;
@属性(保留)NSString*scratchFolder;
@属性(保留)NSMutableString*urlToServerLog;
-(iAction)ParserButton:(id)发送方;
-(NSFileWrapper*)解压缩:(NSData*)zipData;
@结束
这里的问题是urlToServerLog/currentValue处的对象被删除

我发现一个解决方案是复制对象,但我原来的解决方案仍然有效。 在这种情况下,为什么不保留工作


顺便说一句:scratchFolder还与autorelease对象一起使用,它工作得很好。(以完全相同的方式使用,从NSString(autorelease)返回)并分配给scratchFolder。

currentValue
didStartElement:
完成时被释放。我假设
currentValue
是一个类变量?在分配
currentValue
之后,您看到
urlToServerLog
的值是什么?

解析器:didStartElement:namespaceURI:QualifiedNamee:attributes:
,分配一个新字符串并自动释放它:

currentValue = [[[NSMutableString alloc] init] autorelease];
这意味着,当相应的自动释放池耗尽时,此字符串将被释放。通常,如果一个对象需要在方法完成执行后保持活动状态,则您需要拥有它。在您的情况下,此时不要自动释放它(记住在不再需要它时释放它),或使
currentValue
成为
retain
属性,并改用
self.currentValue=…


需要考虑的另一点是:您可能希望使
urlToServerLog
成为
copy
属性,而不是
retain
属性,因为
currentValue
是一个可变字符串,在执行XML解析器时会发生更改。如果您使用
retain
,则
urlToServerLog
属性将l也会更改,因为它指向同一个可变字符串。通过将属性更改为
copy
,您可以有效地复制
currentValue
-对
currentValue
的任何进一步更改都不会影响该属性。

我不明白,我刚开始就不太好。currentValue是ivar,根本不是属性。When我们将currentValue分配给self.urlToServerLog,那不是调用retain on currentValue使计数加上1吗?@Jonathan我已经编辑了我的答案并添加了一段。你可能希望
复制
而不是
保留
@bavariable,还有一些问题。顺便说一句,帮了大忙。谢谢。currentValue不会更改,因为正如您上面所看到的,它正在被再次分配。因此,它的位置将更改,而旧的位置将保持不变。第二,我不能使用copy,因为它是一个可变对象。再次,除了使用mutableCopy(在属性本身上首选)之外,我更喜欢使用其他方法。第三,它是否使用(如果它是属性)“test=[alloc];test=nil;test=[alloc]“和”test=[alloc];test=[alloc]“是一样的吗?第二个示例会调用“release”吗?谢谢。@Jonathan但是
currentValue
已分配(并且在解除分配后不久!阅读我答案中的第一段)只有在
中,如果
,对吗?我想这取决于XML模式。@Jonathan至于你的最后一个问题:是的,它们是一样的,但是你泄漏了一个对象,因为你在分配第二个对象之前没有释放第一个对象。currentValue在didStartElement结束时释放。但是不会将currentValue分配给urlToServerLog是否添加保留计数?currentValue此时已消失。没有保留计数,因为没有对象。但是如果我执行“self.urlToServerLog=[currentValue mutableCopy];”。它仍然有效。因此对象不应该正确消失?这似乎有点道理……试试看。:-)