2012-11-29 67 views
1

我寫了一個小的CLI程序來爲我刪除特定的Safari cookie。在功能上它沒什麼問題,但是它正在拋出關於「自動釋放沒有游泳池」的對象的警告。我的項目啓用了ARC,因此我沒有任何autorelease池。爲什麼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; 

} 

我得到的消息是:

直接運行時釋放二進制(輕微的題外話出現在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時不會顯示)。

我在這裏有點出乎我的意料,任何人都可以告訴我我出錯的地方(以及如何)?

+0

正如大家所說,你需要一個'autorelease'池在你的主。但問題在於它是如何被刪除的(如果這是發生了什麼)。另外,考慮把東西拿出來,並使用像findAndDeleteMatchedCookies這樣的方法。 –

回答

3

ARC仍然需要一個autorelease池。像[NSPredicate predicateWithFormat:filterString]這樣的方法會繼續釋放一個自動釋放對象(儘管自ARC處理它之後不再需要關心自己)。此外,您調用的任何庫方法的內部實現可能會在運行時創建任意多個自動釋放對象。

你應該通過@autoreleasepool機制將你的代碼包裝在autorelease池中。

+0

謝謝。我似乎已經不知何故掩蓋了這一點,直到現在(或至少其影響並未引人注目)消除了它。 – robmathers

1

裹的main整個身體與@autoreleasepool像這樣:

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

所有你需要做的是在主添加autoreleasepool。

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