2013-04-15 80 views
0

我想遷移此代碼與ARC。autoreleasepool和池漏與ARC

我知道我必須使用:

@autoreleasepool {} 

但是我有兩個游泳池排水有問題,我不知道該怎麼辦。

- (void)downloadImageToCache:(NSString*)_urlImage 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    if (!(_urlImage) || (_urlImage == nil)) 
    { 
     [pool drain]; 
     return; 
    } 

    NSURL *url = [NSURL URLWithString:_urlImage]; 
    NSData *data = [[[NSData alloc] initWithContentsOfURL:url] autorelease]; 

    if (data != nil) 
    { 
     ...do something... 
    } 
    else 
    { 

     ...do something... 
    } 
    [pool drain]; 
} 
+0

目前的方法有什麼問題? – 2013-04-15 19:55:30

+1

@ H2CO3:ARC不允許使用。 –

+0

@MartinR我相信我見過'@autoreleasepool {}'和ARC一起使用。 (但是,無論如何,誰在乎ARC?我不這麼認爲)。 – 2013-04-15 20:01:37

回答

1

你可以只是「初回」從自動釋放池,這將釋放從池中 所有對象:

- (void)downloadImageToCache:(NSString*)_urlImage 
{ 
    @autoreleasepool {  
     if (!(_urlImage) || (_urlImage == nil)) 
     { 
      // no need (not allowed) to call `drain` 
      return; 
     } 

     NSURL *url = [NSURL URLWithString:_urlImage]; 
     NSData *data = [[[NSData alloc] initWithContentsOfURL:url] autorelease]; 

     if (data != nil) 
     { 
      ...do something... 
     } 
     else 
     { 

      ...do something... 
     } 
     // no need (not allowed) to call `drain` 
    } 
} 
0

隨着新@autorelease塊語法,池將被耗盡當執行退出塊時。有關更多信息,

0

也許

- (void)downloadImageToCache:(NSString*)_urlImage 
{ 
    @autoreleasepool { 

     if (!(_urlImage) || (_urlImage == nil)) 
     { 
      return; //leaves @autoreleasepool block, automatically drains 
     } 

     NSURL *url = [NSURL URLWithString:_urlImage]; 
     NSData *data = [[[NSData alloc] initWithContentsOfURL:url] autorelease]; 

     if (data != nil) 
     { 
      ...do something... 
     } 
     else 
     { 

      ...do something... 
     } 
    } //leaves @autoreleasepool block, automatically drains 
} 

AutoreleasePools:所以,你可以做到這一點

- (void)downloadImageToCache:(NSString*)_urlImage 
{ 
    @autoreleasepool { 
     if (!(_urlImage) || (_urlImage == nil)) 
     { 
      return; 
     } 

     NSURL *url = [NSURL URLWithString:_urlImage]; 
     NSData *data = [[NSData alloc] initWithContentsOfURL:url]; 

     if (data != nil) 
     { 

     } 
     else 
     { 

     } 
    } 
} 

來源:Apple Documentation

2

包裹了整個事情。不要擔心回報。它會弄清楚。

I.e.編譯器將其轉換爲邏輯上等同:(或者你可以明確地清理邏輯)

- (void)downloadImageToCache:(NSString*)_urlImage 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    if (!(_urlImage) || (_urlImage == nil)) 
    { 
    //[pool drain]; 
    //return; 
    } else { 

    NSURL *url = [NSURL URLWithString:_urlImage]; 
    NSData *data = [[[NSData alloc] initWithContentsOfURL:url] autorelease]; 

    if (data != nil) 
    { 
     ...do something... 
    } 
    else 
    { 
     ...do something... 
    } 
    } 
    [pool drain]; 
} 

其簡化爲:

- (void)downloadImageToCache:(NSString*)_urlImage { 
    @autoreleasepool { 
    if (_urlImage != nil) { 

     NSURL *url = [NSURL URLWithString:_urlImage]; 
     NSData *data = [[[NSData alloc] initWithContentsOfURL:url] autorelease]; 

     if (data != nil) { 
     // ...do something... 
     } else { 
     //...do something... 
     } 
    } 
    } 
} 

或許(更少的嵌套的凹痕永遠是我的偏好):

- (void)downloadImageToCache:(NSString*)_urlImage { 
    if (_urlImage == nil) { 
    NSLog(@"[%@ %@] Error Message", NSStringFromClass([self class]), NSStringFromSelector(_cmd)); 
    return; 
    } 

    @autoreleasepool { 

    NSURL *url = [NSURL URLWithString:_urlImage]; 
    NSData *data = [[[NSData alloc] initWithContentsOfURL:url] autorelease]; 

    if (data != nil) { 
     // ...do something... 
    } else { 
     //...do something... 
    } 
    } 
} 
+2

只是注意到你仍然可以在ARC中使用'@ autoreleasepool'。我不確定。但是,我所消耗的內存從1.5 GB降至100 MB。 – funroll

0

此代碼中有兩個排水管的唯一原因是因爲它在第一次排水之後立即返回。只需將代碼包裝在@autoreleasepool中,無論返回路徑如何,它在退出時都會消失。