为什么在启用 ARC 的情况下发生此自动发布错误



我写了一个小的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时,当我提供适当的参数时,这不会显示)。

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

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

应通过@autoreleasepool机制将代码包装在自动发布池中。

@autoreleasepool包裹整个main体,如下所示:

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

您需要做的就是在 main 中添加一个自动发布池。

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

最新更新