好的,所以我已经对此做了大量的研究,并且已经把我的头发拉了几天试图找出以下代码泄漏的原因:
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
UIImage *comicImage = [self getCachedImage:[NSString stringWithFormat:@"%@%@%@",@"http://url/",comicNumber,@".png"]];
self.imageView = [[[UIImageView alloc] initWithImage:comicImage] autorelease];
[self.scrollView addSubview:self.imageView];
self.scrollView.contentSize = self.imageView.frame.size;
self.imageWidth = [NSString stringWithFormat:@"%f",imageView.frame.size.width];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
self.imageView和self.scrollView都是@propety(非原子,保留)并在我的dealloc中发布..在代码中的其他任何地方都不使用imageView。此代码也在主线程的线程中运行。如果我在我的设备上运行此代码,如果我不断加载此视图,它将很快耗尽内存。但是,我发现如果我注释掉以下行:
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
UIImage *comicImage = [self getCachedImage:[NSString stringWithFormat:@"%@%@%@",@"http://url/",comicNumber,@".png"]];
self.imageView = [[[UIImageView alloc] initWithImage:comicImage] autorelease];
//[self.scrollView addSubview:self.imageView];
self.scrollView.contentSize = self.imageView.frame.size;
self.imageWidth = [NSString stringWithFormat:@"%f",imageView.frame.size.width];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
无论加载视图多少次,内存使用都会变得稳定。我已经完成了我能想到的一切,看看为什么会泄漏,但据我所知,我的所有发布都是直接的。谁能看到我失踪的东西?
答案 0 :(得分:1)
您在初始化时自动释放您的imageview,然后通过将其分配给self.imageView来保留它,然后将其添加为子视图再次保留它。因此,当池耗尽时,它会收到一条释放消息。当它作为子视图被删除时,它会获得一条释放消息。然后,如果你dealloc,它会获得第三个发布消息。其中一个没有发生。你说它是以dealloc发布的,所以不是这样。可以信任自动释放池在某个时刻消耗掉,所以不是这样。我要么确保在某个时候将其作为子视图删除,要么删除一个保留调用。
并且......不应该这样:
self.imageView = [[[UIImageView initWithImage:comicImage] autorelease];
是吗?:
self.imageView = [[UIImageView alloc] initWithImage:comicImage];
答案 1 :(得分:0)
调用此行时:
[self.scrollView addSubview:self.imageView];
self.imageView由其超级视图保留,当您不再需要imageView时,您应该调用:
[self.imageView removeFromSuperview];
这将在self.imageView上调用release。
P.S。您可以通过调用
来跟踪您的参考计数NSLog(@"RefCount: %d", [self.imageView retainCount]);
在
上面添加此行self.imageView = [[[UIImageView initWithImage:comicImage] autorelease];
跟踪refCount。 (更好的选择是使用乐器,但你已经知道:))
编辑:当你保留这样的属性时,[[alloc] init]对象是一个好习惯:
UIView *myView = [[UIView alloc] init];
self.myCustomView = myView;
[myView release];
否则你将获得self.myCustomView保留两次。
答案 2 :(得分:0)
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
精细。
UIImage *comicImage = [self getCachedImage:[NSString stringWithFormat:@"%@%@%@",@"http://url/",comicNumber,@".png"]];
除非你遵循标准的Cocoa模式(这种方法不是这样),否则不要调用方法get*
。只需将其称为cachedImage:
。
self.imageView = [[[UIImageView initWithImage:comicImage] autorelease];
您错过了alloc
电话;应该是:
self.imageView = [[[UIImageView alloc] initWithImage:comicImage] autorelease];
或者(如果你想避免自动释放池;可能不是这里的问题):
UIImageView *iV = [[UIImageView alloc] initWithImage:comicImage];
self.imageView = iV;
[iV release];
[self.scrollView addSubview:self.imageView];
self.scrollView.contentSize = self.imageView.frame.size;
self.imageWidth = [NSString stringWithFormat:@"%f",imageView.frame.size.width];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
一切都很好。如果有泄漏,可能是因为imageView
没有在dealloc中释放,或者其他东西挂在它上面(scrollView
没有被释放,偶然?)。仪器可以很好地追踪泄漏等......
“泄漏”工具寻找的是不再有任何引用的对象。在这种情况下,你很可能还有引用。
坦率地说,鉴于您很容易通过重复来重现增长,因此快照分析很可能非常适用。