__NSAutoreleaseNoPool(): Object 0x753c2f0 of class

2020-06-19 06:10发布

问题:

I haven't noticed my console output for a while and I've suddenly noticed lots of weird errors.

__NSAutoreleaseNoPool(): Object 0x753c2f0 of class General autoreleased with no pool in place - just leaking

__NSAutoreleaseNoPool(): Object 0x753c300 of class __NSArrayM autoreleased with no pool in place - just leaking

I've no idea where this happening?

Edit..

I use this

[self performSelectorInBackground:@selector(startupStuff) withObject:sender];

With statupStuff I have this

General *rdb = [[General alloc] autorelease];
[rdb refreshDBData];

The Errors happen shortly after code in the refreshDBData method.

回答1:

Autorelease pools are tied to threads. If you create a thread through performSelectorInBackground then you need to create and destroy an autorelease pool for yourself. So you need startupStuff to look like this:

- (void)startupStuff:(id)sender
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    // ... everything else you were doing ...

    [pool drain]; //see comment below
}

Addition: Richard below makes the point that drain is preferable to release to acknowledge that (on the desktop, not yet on iOS) you may be running with a garbage collector. Apple's specific words are (source):

In a garbage-collected environment, sending a drain message to a pool triggers garbage collection if necessary; release, however, is a no-op. In a reference-counted environment, drain has the same effect as release. Typically, therefore, you should use drain instead of release.

So I've corrected my example. Suffice to say, this specific question is to do with the iPhone and currently there is no garbage collection on that device. So the originating poster is in the "drain has the same effect as release" camp, not the "drain ... triggers garbage collection if necessary; release, however, is a no-op" camp.



回答2:

This:

General *rdb = [[General alloc] autorelease];

Is wrong. There should always be a call to an initializer; to -init, at the least.



回答3:

Try this

[self performSelectorInBackground:@selector(startupStuff) withObject:sender];

-(void)startupStuff:(id)sender
{

   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

   General *rdb = [[General alloc] init];

   [rdb refreshDBData];

   [rdb release];

   [pool release];

}

If its not working too then you need to check refreshDBData method.. you are doing something wrong there