0

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

Why would the following code section print the leak error above?

+ (BOOL)getSkipFlag
{

    NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
    if ( ![defs objectForKey:_BOOK_ID] )
    {
        [defs setObject:@"yyyy" forKey:_BOOK_ID];

        [defs synchronize];
    }

    if ( ![[defs objectForKey:_BOOK_ID] isEqualToString:@"xxxx"] )
    {
        return NO;
    }

    return skipFlag;
}

usage

if ( ![ClassXYZ getSkipFlag] )
....

I don't use a new thread so I should not have a new autorelease pool set up.

Note: NSString *temp = [[NSBundle mainBundle] pathForResource:_CONFIG_PLIST ofType:@"plist"]; - would print the same error I am using iOS 5.1

Thanks for any insight.

UPDATE: ClassXYZ.m ... static BOOL skipFlag = NO;

setter: + (void)setSkipFlag:(BOOL)boolValue { skipFlag = boolValue; }

usage: [ClassXYZ setSkipFlag:YES];

used in static void convert_uri_to_file_name(struct mg_connection *conn, const char *uri, char *buf, size_t buf_len)

Omar you had a good point about where it is used. It turns out if I ClassXYZ's own instance methods for example, it works without errors.

Zsolt
  • 3,648
  • 3
  • 32
  • 47
  • very nice case :), would please provide more code around if ( ![ClassXYZ getSkipFlag] ) or posting the caller function that prints this – Omar Abdelhafith Jun 11 '12 at 10:23
  • just out of curiosity, if you put the function call inside an @autorelease does the log goes away? – Omar Abdelhafith Jun 11 '12 at 13:25
  • well Omar, looks like you just solved my problem. added @autoreleasepool{ ... } and the log disappeared. For some reason I assumed the this will not work for a non-arc project and never bothered trying it. [I should have checked this before http://stackoverflow.com/questions/7950583/autoreleasepool-without-arc]. So thank a lot, and please add an answer so I can accept yours as the resolution. – Zsolt Jun 12 '12 at 05:37
  • interesting that if I created an autorelease pool and then drained it at the end it did not work. – Zsolt Jun 13 '12 at 06:27

2 Answers2

1

Generally, The autorelease pool for main thread would be created at the first line of main function. Anything that runs before main function would see that the autorelease pool is absent.

+load function is one reason that would cause the leaks, because it runs before main function. If that's the case, just consider using +initialize instead.

tia
  • 9,518
  • 1
  • 30
  • 44
  • thanks tia. added +(void)initialize{skipFlag=NO;} but it does not help. I used static BOOL skipFlag; for this case in the .m file. – Zsolt Jun 11 '12 at 12:12
0

just out of curiosity, if you put the function call inside an @autorelease that log should go away

Omar Abdelhafith
  • 21,163
  • 5
  • 52
  • 56