2012-05-29 94 views
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]; 
} 

回答

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

你保持過度的保留的對象,因爲它已經被你存儲它在字典中擁有。如果你刪除它形成的字典,但仍希望有周圍,比你應該保留它或使用保留財產。

嘗試:

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

的UIView的-addSubview:保留子視圖:

討論
這種方法保留看法,並將其下一個響應者的 接收器,這是它的新上海華。

當你在dealoc中釋放它們時,你會過度釋放image和imageView,但是也會對它們調用autorelease。

+0

好吧,我有點困惑(對不起,我是新來的內存管理,因爲我一直在使用ARC)... ImageBox返回一個autoreleased對象。我以爲你需要保留這一點。此外,如果我刪除保留,我的應用程序崩潰。我假設當我在應用程序 –

+3

中稍後嘗試從RemoveSubview中移除它時,會發生崩潰,它被視圖保留。所以如果它崩潰,比你必須在其他地方有一個過度釋放/欠保留。可能在ImageBox中。請顯示代碼。 – vikingosegundo

+0

我修改了上面的代碼以顯示更多內容。在新的搜索中,我通過從超級視圖中移除來清除圖像 –

2

這是因爲有一個明確的,不必要的retain

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

請看下面我的回覆 –