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を使用して以来、メモリ管理は初めてです。他に潜在的なリークが発生した場合はお知らせください。Leaks Instrumentツールを使用しましたが、リークがないと表示されます。しかし、私がリークを導入しようとしたので、それが事実であるかどうかはわかりませんが、それでもリークはないと言われていました。以下はすべての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]];

オブジェクトを保存しているディクショナリによって既に所有されているため、オブジェクトを保持しすぎています。ディクショナリから削除しても、保持したい場合は、オブジェクトを保持するか、保持プロパティを使用する必要があります.

試す:

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

UIView-addSubview:はサブビューを保持します。

考察
このメソッドはビューを保持し、次のレスポンダを新しいスーパービューであるレシーバに設定します。

イメージ、imageView を dealoc でリリースするときに過剰にリリースしていますが、autorelease も呼び出しています。

于 2012-05-29T00:09:05.333 に答える