【问题标题】:Potential leak of an object allocated - not sure why分配的对象的潜在泄漏 - 不知道为什么
【发布时间】:2012-05-29 00:06:12
【问题描述】:

有人可以帮我理解为什么静态分析器说在 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];
}

【问题讨论】:

    标签: objective-c ios memory-management memory-leaks


    【解决方案1】:

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

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

    【讨论】:

    • 请看下面我的回复
    【解决方案2】:
    [imageGallery addSubview:[[ImageBox createImageBoxWitImageURL:[item objectForKey:@"tbUrl"]] retain]];
    

    您过度保留了保留对象,因为它已经由您存储它的字典拥有。如果您要将它从字典中删除,但仍想保留,那么您应该保留它或使用保留财产。

    尝试:

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

    UIView 的-addSubview: 保留子视图:

    讨论
    此方法保留视图并将其下一个响应者设置为 接收者,这是它的新超级视图。

    当你在dealoc中释放它们时,你过度释放了图像,imageView,但也对它们调用了autorelease。

    【讨论】:

    • 好吧,我有点困惑(抱歉,我一直在使用 ARC,所以我是内存管理的新手)... ImageBox 返回一个自动释放的对象。我认为你需要保留它。此外,如果我删除保留,我的应用程序会崩溃。我假设当我稍后在我的应用程序中尝试 removeFromSubview 时发生崩溃
    • 它被视图保留。因此,如果它崩溃,那么您必须在其他地方过度释放/保留不足。可能在 ImageBox 类中。请出示代码。
    • 我修改了上面的代码以显示更多内容。在新的搜索中,我通过从超级视图中删除来清除图像
    • 您应该显示 ImageBox 中与内存管理有关的任何代码。
    • 好的,我添加了整个 imagebox.c 方法,并对我的问题进行了更多解释。让我知道它是否足够。我非常感谢您的帮助和时间!顺便说一句,imageView 和 image 成员函数是非原子的,保留属性
    猜你喜欢
    • 2012-01-01
    • 1970-01-01
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 2012-01-05
    相关资源
    最近更新 更多