0

我想用 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];
}
4

5 回答 5

2

把整个东西包起来。不用担心回报。它会弄清楚的。

即编译器会将其转换为逻辑等效的:(或者您可以显式清理逻辑)

- (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...
    }
  }
}
于 2013-04-15T20:00:44.747 回答
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`
    }
}
于 2013-04-15T19:59:18.350 回答
0

使用新的@autorelease 块语法,当执行退出块时,池将被耗尽。所以你可以这样做:

- (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

于 2013-04-15T19:59:51.937 回答
0

也许:

- (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 文档

于 2013-04-15T20:00:24.050 回答
0

这段代码中有两个排水管的唯一原因是因为它在第一次排水管之后很早就返回了。只需将代码包装在 中@autoreleasepool,无论遵循哪个返回路径,它都会在退出时耗尽。

于 2013-04-15T20:01:20.103 回答