我是Obj的新手,我正在尝试一些东西。我偶然发现了一个泄漏问题,并想知道背后的逻辑原因。
下面的代码泄漏:
(textViewAttrStr is an instance variable of type NSMutableAttributedString)
-(void) init:(NSString*)str
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
textViewAttrStr = [[NSMutableAttributedString alloc] initWithString:@"Hello "];
NSMutableAttributedString *part1String = [[NSMutableAttributedString alloc] initWithString:str];
[textViewAttrStr appendAttributedString:part1String];
NSMutableAttributedString *part2String = [[NSMutableAttributedString alloc] initWithString:@"!!!"];
[textViewAttrStr appendAttributedString:part2String];
[textViewAttrStr retain];
[part1String release];
[part2String release];
[pool drain];
}
-(void) dealloc
{
if(textViewAttrStr != nil)
{
[textViewAttrStr release];
}
[super dealloc];
}而下面的代码不会泄漏:
-(void) init:(NSString*)str
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableAttributedString* tvas = [[NSMutableAttributedString alloc] initWithString:@"Hello "];
NSMutableAttributedString *part1String = [[NSMutableAttributedString alloc] initWithString:str];
[tvas appendAttributedString:part1String];
NSMutableAttributedString *part2String = [[NSMutableAttributedString alloc] initWithString:@"!!!"];
[tvas appendAttributedString:part2String];
textViewAttrStr = tvas;
[textViewAttrStr retain];
[part1String release];
[part2String release];
[tvas release];
[pool drain];
}
-(void) dealloc
{
if(textViewAttrStr != nil)
{
[textViewAttrStr release];
}
[super dealloc];
}谁能解释一下原因吗?
发布于 2011-08-12 03:22:43
第二个例子显示,您不明白为什么在第一个示例中有漏洞,所以您可以选择进行实验,这似乎是一种可以理解的方法。
在第二个示例中,textViewAttrStr和tavs本质上是相同的。它们都是对内存中相同对象的引用(或指针)。
所以,当你这样做时:
textViewAttrStr = tvas;
[textViewAttrStr retain];
//...
[tvas release];要在此对象上保留的调用与对该对象的释放调用是平衡的。这几乎什么都没做。在这里删除release和release提供了相同的功能。删除这些后,对象的引用计数为1,因为您调用了alloc,当dealloc命中时,它将达到0并被释放。
现在,在您的第一个示例中,您的对象正在分配(引用计数为1),然后保留(引用计数为2),当dealloc命中时,它将达到1的引用计数,而您的对象将不会被释放,从而泄漏。因此,这里的解决方案是删除要保留的调用。
顺便说一下,在向对象发送发布消息之前检查对象是否为零是不必要的,因为向nil发送消息没有任何作用。
发布于 2011-08-11 14:25:54
第一个例子的问题是额外的保留。您需要删除它,因为在用textViewAttrStr创建[[NSMutableAttributedString alloc] initWithString:@"Hello "];时,它已经被保留了。
//Remove this line in the first example
[textViewAttrStr retain];发布于 2011-08-11 14:25:35
第一个例子:
textViewAttrStr = [[NSMutableAttributedString alloc] initWithString:@"Hello "];
//...
[textViewAttrStr retain];第二个例子
NSMutableAttributedString* tvas = [[NSMutableAttributedString alloc] initWithString:@"Hello "];
//...
[tvas release];现在您应该看到,在第一个示例中,您已经分配了/init并保留了它,哇。
第二个例子,您正确地分配了/init然后发布了。
简单的规则:如果你分配或复制或保留,你必须在某个时候释放。如果它是类变量,则在dealloc中释放,否则在离开作用域之前释放。
https://stackoverflow.com/questions/7027550
复制相似问题