自定义UIView泄漏内存 - iPhone / iPad / iOS应用程序开发

时间:2011-02-13 04:16:38

标签: iphone objective-c ios xcode memory-management

我有一个viewcontroller,可以在uiscrollview中重复定位6个项目。然而,即使我将uiscrollview中的项目数量限制为6,我仍然在更新其位置和图像时泄漏内存。如果下面代表uiscrollview中的单位的代码被正确编码,有人可以告诉我吗? startLoad是我重新加载图像后调用的方法。

#import "ScrollUnit.h"

@implementation ScrollUnit
@synthesize index;
@synthesize ProductToDisplay;

- (id)initWithFrame:(CGRect)frame {

    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code.
    }
    return self;
}        

-(void)startLoad
{   
    [imageview removeFromSuperview];
    [imageview release];

    NSOperationQueue *queue = [NSOperationQueue new];
    NSInvocationOperation *operation = [[NSInvocationOperation alloc]
                                        initWithTarget:self
                                              selector:@selector(loadImage) 
                                                object:nil];

    [queue addOperation:operation];
    [operation release];
}

-(void)loadImage 
{
    NSString *myimageName = [self.ProductToDisplay valueForKey:IMAGEKEY];
    NSString *myimageUrl = [NSString stringWithFormat:@"%@/%@",IMAGE_SERVICE,myimageName];

    NSData* imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:myimageUrl]];

    UIImage* image = [[[UIImage alloc] initWithData:imageData] autorelease];
    [imageData release];
    [self performSelectorOnMainThread:@selector(displayImage:) withObject:image waitUntilDone:NO];
}

- (void)displayImage:(UIImage *)image 
{   
    imageview = [[[UIImageView alloc] initWithFrame:CGRectMake(9, 0, 320, 320)]retain];
    imageview.contentMode = UIViewContentModeScaleAspectFit;
    imageview.backgroundColor = [UIColor whiteColor];
    imageview.image = image;
    [self addSubview:imageview];
    [imageview release];
    //[image release];
}

- (void)dealloc {
    [super dealloc];
}

@end

2 个答案:

答案 0 :(得分:3)

删除此行上的retain消息,您应该全部设置:

imageview = [[[UIImageView alloc] initWithFrame:CGRectMake(9, 0, 320, 320)]retain];

您需要执行此操作的原因是您已通过调用alloc 来拥有该对象,因此此时相对引用计数为2

一旦您调用addSubview:,传递imageview,引用计数就会变为3,然后在您2后向右追溯到release它在下一行。

因此,一旦该对象在release中发送-dealloc,您仍然会被卡住,因为引用计数现在是1,而不是您预期的0

答案 1 :(得分:1)

还有另一件可能有bug(或没有)的小东西。在displayImage方法中指定之前,不要发布 imageview 。只要只调用startLoad就可以了,但如果从外部调用displayImage,那么你仍然会泄漏。

您可能希望使用保留的属性,然后合成getter和setter方法。这样,iOS将在保留新分配的对象之前释放您之前的作业。那说你需要释放创建的图像视图,如果你创建它,你必须使用“self.imageview”,以确保你使用setter(setImageview)。