【问题标题】:Why is this autorelease error occurring with ARC enabled?为什么在启用 ARC 的情况下会出现此自动释放错误?
【发布时间】:2012-11-29 00:37:19
【问题描述】:

我编写了一个小型 CLI 程序来为我删除特定的 Safari cookie。在功能上它很好,但它会抛出关于对象“自动释放而没有到位池”的警告。我的项目启用了 ARC,因此我没有任何自动释放池。

这是我的代码:

// NSLog replacement from http://stackoverflow.com/a/3487392/1376063
void IFPrint (NSString *format, ...) {
    va_list args;
    va_start(args, format);

    fputs([[[NSString alloc] initWithFormat:format arguments:args] UTF8String], stdout);
    fputs("\n", stdout);

    va_end(args);
}

int main(int argc, const char * argv[])
{
    NSString *urlSearchString;
    if (argc > 1) {
        urlSearchString = [[NSString alloc] initWithUTF8String:argv[1]];
    }
    else {
        IFPrint(@"No URL provided, quitting.");
        return 1;
    }

    NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];

    NSString *filterString = [[NSString alloc] initWithFormat:@"domain ENDSWITH '%@'", urlSearchString];
    NSPredicate *filter = [NSPredicate predicateWithFormat:filterString];

    NSArray *matchedCookies = [cookieStorage.cookies filteredArrayUsingPredicate:filter];

    for (int i = 0; i < matchedCookies.count; i++) {
        [cookieStorage deleteCookie:[matchedCookies objectAtIndex:i]];
    }

    IFPrint(@"Removed %li cookies", matchedCookies.count);
    return 0;

}

我得到的信息是:

objc[15502]: Object 0x107b2bf00 of class NSThread autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug

出现在 Xcode 调试器中或直接运行发布二进制文件时(稍微题外话:这些消息不应该从“发布”构建中剥离吗?)。导致它的行似乎是:

NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];

同样,如果我在不传递参数的情况下运行它,我会收到类似的消息:

objc[15630]: Object 0x100114ed0 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
objc[15630]: Object 0x100114f80 of class __NSCFData autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug

这似乎来自我正在使用的 IFPrint 函数(但是,当我提供正确的参数时,当我使用 IFPrint 时,这不会出现)。

我在这里有点不知所措,谁能告诉我我在哪里(以及如何)出错了?

【问题讨论】:

  • 正如大家所说,您的主池中需要一个 autorelease 池。但问题是它最初是如何被删除的(如果是这样的话)。另外,请考虑将这些内容从主要内容中取出并使用 findAndDeleteMatchedCookies 之类的方法。

标签: objective-c automatic-ref-counting autorelease


【解决方案1】:

ARC 仍然需要一个自动释放池。像[NSPredicate predicateWithFormat:filterString] 这样的方法会继续释放一个自动释放的对象(尽管你不再需要关心自己,因为 ARC 处理了它)。此外,您调用的任何库方法的内部实现都可能在运行时创建任意数量的自动释放对象。

您应该通过@autoreleasepool 机制将代码包装在自动释放池中。

【讨论】:

  • 谢谢。直到现在,我似乎以某种方式掩盖了这一点并侥幸逃脱(或者至少其影响不明显)。
【解决方案2】:

像这样用@autoreleasepool包裹main的整个主体:

int main(int argc, const char * argv[])
{
  @autoreleasepool 
  {
    // your code
  }
}

【讨论】:

    【解决方案3】:

    您需要做的就是在您的主目录中添加一个自动释放池。

    int main(int argc, const char * argv[])
    { 
         @autoreleasepool
         {
             //Your code
         }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-05
      • 1970-01-01
      • 2012-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-24
      相关资源
      最近更新 更多