2

有人可以帮我理解为什么静态分析器说在 for(NSDictionary...) 行存在潜在泄漏吗?

- (void)imageSearchController:(id)searchController gotResults:(NSArray *)results
{
    if ([results count] == 0) {
        UIAlertView *alertView = [[[UIAlertView alloc] initWithTitle:nil 
                                                            message:@"I was not able to find anything! Please try again."  
                                                           delegate:self cancelButtonTitle:@"OK" 
                                                  otherButtonTitles:nil] autorelease];
        [alertView show];
    } else {
        [self increaseSearchIndex];

        for (NSDictionary *item in results) {
            [imageGallery addSubview:[[ImageBox createImageBoxWitImageURL:[item objectForKey:@"tbUrl"]] retain]];
        }

        if (searchIndex <= 60) {
            [imageGallery addSubview:buttonBox];
        } else {
            [buttonBox removeFromSuperview];
        }

        //position the images with respect to each other and screen orientation
        [self positionImages];
    }
    [activityIndicator stopAnimating];
}

- (void)clearImages 
{
    for (UIView *subview in [imageGallery subviews]) {
        if ([subview isMemberOfClass:[ImageBox class]] || [subview isMemberOfClass:[ButtonBox class]]) {
            [subview removeFromSuperview];
        }
    }
}

图像框将带有填充的图像返回给上述其他其他方法。自从我过去一直在使用 ARC 以来,我是内存管理的新手。如果您发现其他潜在的泄漏,请告诉我。我使用了泄漏仪器工具,它说没有泄漏!但我不确定情况是否如此,因为我试图引入泄漏,但它仍然说没有。以下是所有 ImageBox 代码:

@interface ImageBox : UIView

@property (nonatomic, retain) UIImageView *imageView;
@property (nonatomic, retain) UIImage *image;

+ (id)createImageBoxWitImageURL:(NSString *)imageURL;

@end

@implementation ImageBox

@synthesize imageView;
@synthesize image;
- (id)initWithImageURL:(NSString *)imageURL
{
    self = [super init];
    if (self) {
        int padding = 10;
        int imageHeight = 108;
        int imageWidth = 108;

        int paddingBoxHeight = imageHeight + (2 * padding);
        int paddingBoxWidth = imageWidth + (2 * padding);

        NSData* imageData = [[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:imageURL]];
        image = [[[UIImage alloc] initWithData:imageData] autorelease];
        [imageData release];

        imageView = [[[UIImageView alloc] initWithImage:image] autorelease];
        imageView.layer.masksToBounds = YES;
        imageView.layer.cornerRadius = 13.0;
        imageView.contentMode = UIViewContentModeScaleAspectFill;
        CGRect imageFrame = CGRectMake(padding, padding, imageWidth, imageHeight);
        [imageView setFrame:imageFrame];

        CGRect paddingBoxFrame = CGRectMake(0, 0, paddingBoxWidth, paddingBoxHeight);
        [self setFrame:paddingBoxFrame];
        [self addSubview:imageView];

        self.backgroundColor = [UIColor clearColor];
    }
    return self;
}

+ (id)createImageBoxWitImageURL:(NSString *)imageURL
{
    ImageBox *imageBox = [[self alloc] initWithImageURL:imageURL];
    return [imageBox autorelease];
}

- (void)dealloc
{
    [imageView release];
    [image release];
    [super dealloc];
}
4

2 回答 2

2

这是因为有一个明确的、不必要的retain.

[imageGallery addSubview:
  [[ImageBox createImageBoxWitImageURL:[item objectForKey:@"tbUrl"]] retain]];
                                                                     ^^^^^^
于 2012-05-29T00:08:37.327 回答
1
[imageGallery addSubview:[[ImageBox createImageBoxWitImageURL:[item objectForKey:@"tbUrl"]] retain]];

you are over-retaining the retaining the object, as it is already owned by the dictionary you are storing it in. if you would remove it form the dictionary, but still wants to have around, than you should retain it or use a retaining property.

try:

[imageGallery addSubview:[ImageBox createImageBoxWitImageURL:[item objectForKey:@"tbUrl"]]];

UIView's -addSubview: retains the subview:

Discussion
This method retains view and sets its next responder to the receiver, which is its new superview.

You are over-releasing image, imageView, as you release them in dealoc, but also call autorelease on them.

于 2012-05-29T00:09:05.333 回答