autoreleased with no pool warning? - objective-c

I have audio class that sample the buffer and with NSNotification it calls another class and send a data(int).
I get this warning that runs many many times a second:
class __NSCFNumber autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool()
class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
what does it means?
yes I have NSNumber in that class and NSString.
they are not allocated.
do I need another thread?
what's wrong?

It means that, for whatever thread that code is running on, no autorelease pool has been set up before that code runs. For AppKit- or UIKit-based apps, the framework normally managed one for you on the main thread, but you'll still need to create them yourself if you're using other threads. For apps that are not based on AppKit or UIKit, you'll pretty much always need to make sure there's an autorelease pool around when you're running Objective-C code.

Do you use an autorelease pool in your main() function in the application? Do you use the autoreleased instances (yes, I know, you didn't alloc-init them, but [NSNumber numberWith...] returns an alloc-init-autoreleased object) in a thread other than the main thread? If you haven't initially set up an autorelease pool, or you're using multiple threads, you must create an individual NSAutoreleasePool for each thread.

Related

Thread with lot of autoreleased objectIs is it mandatory to use autorelease pool on this scenario if yes/no why?

Consider we are implementing our own thread with lot of autoreleased object. Is it mandatory to use autorelease pool on this scenario if yes/no why?
It's mandatory to have an autorelease pool on any thread that you create, because Cocoa internals expect there to be one in place and you will leak memory if it isn't there.
Cocoa always expects there to be an autorelease pool available. If a pool is not available, autoreleased objects do not get released and your application leaks memory. If you send an autorelease message when a pool is not available, Cocoa logs a suitable error message.
Applications that link in Objective-C frameworks typically must create at least one autorelease pool in each of their threads.
It is mandatory even with a single autoreleased object, because otherwise it will leak.

Objective-c: returning autoreleased object from method

What prevents the autoreleased instance of NSArray from being released before it's used in the method it's returned to?
- (NSArray *) f {
return [NSArray array];
}
- (void) g {
NSArray *a = [self f];
// do something with a
}
What prevents the autoreleased instance of NSArray from being released
before it's used in the method it's returned to?
Autorelease pools are per thread. That is, an autoreleased object is, effectively, a delayed call to release that happens on a per thread basis.
Thus, if there is no call to drain between the caller and the callee, there is no way the autoreleased object will be released because of a pool drain (barring serious threading stupidity).
In general, pools are drained at very well specified times, like Kevin said:
• the run loop will drain the pool at the bottom of each pass through the loop
• dispatched blocks via GCD will execute within a pool context that'll be drained "every now and then" (implementation detail). NSOperationQueue behaves similarly
• other threads are responsible for doing it themselves
Thus, in your simple example, the code execution is quite linear and, by inspection, there can be no drain in that thread of execution between the return and the use in the caller.
(Note that this is also one of the reasons why retainCount is useless; it neither accounts for any "delayed release" calls caused by autorelease nor does it quantify any per-thread retains. In reality, you should think of retains/releases as being entirely per-thread; if you retain an object on a thread you should release it on the same thread unless you are explicitly transferring ownership from one thread to another.)
Autoreleased objects are only released when their surrounding pool is drained. This is not some magical process that happens behind the scenes. It's a deterministic event that happens at well-defined times. In general, the pool is drained when control returns to the run loop. If you establish your own nested pool, then you control when that drains.
The autorelease pool is drained during an iteration of the event loop. Since it's that drain that causes release messages to be sent to the autoreleased objects, they are still valid in the calling method.

Breakpoint pointing out "objc_autoreleaseNoPool"

So I'm debugging an app in preperation for its app so release, and I enabled a universal breakpoint for "All Exceptions". Since then, everytime I run the app, the console prints:
Catchpoint 2 (throw)Pending breakpoint 1 - "objc_exception_throw" resolved
objc[11765]: Object 0x8f18ff0 of class __NSCFLocale autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
objc[11765]: Object 0x8f190a0 of class __NSCFNumber autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
objc[11765]: Object 0x8f1fef0 of class __NSCFLocale autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
Literally printed 3 times. I have no idea what this means but it looks bad. Any advice would be appreciated.
New Info
I determined where my issue lies by creating a swizzled autorelease method.
I dont recommend doing that unless you know what you are doing, however this is what I found out.
+ (void) load; //Method is called outside the original autorelease pool.
+ (void) initialize; // Method is called outside the original autorelease pool.
NSThread creates its own thread, the called method should be wrapped in an autorelease pool.
Grand Central Dispatch takes care of adapting over the autorelease pool when using the "dispatch_..." commands. however, when you dispatch manually. you may want to wrap it in an autorelease pool.
Also, ARC does not handle letting you know that an autorelease will happen outside a pool.
Therefore if you are using ARC and know that you will be outside the autorelease pool. And there is nothing you can do about that. You will want to avoid all convenience methods.
use this.
[[NSString alloc] initWithFormat:#"%#",myObject];
instead of this
[NSString stringWithFormat:#"%#",myObject];
this will allow the arc system to retain and release, but the underlying autorelease done by the convenience method will be skipped as you will not have used the convenience method.
Hope that helps.
Original Answer
Ok, I dont feel this question was answered with enough detail.
the message being presented was
objc[1310]: Object 0x34f720 of class SimpleKeychain autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
The debugger is pointing out a possible breakpoint that will help you debug the situation. Now while this breakpoint really did little to help debug the situation. I think that it is important to know how to add that breakpoint to the debugger and so I spent the time tinkering with it (after scouring the internet and finding nothing) until I got it to break on that error.
It is kind of annoying that break on all errors does not catch this, but here are the steps to add the breakpoint to the debugger.
first thing you want to do is select the debugger's breakpoint navigator
by clicking on this tab
next you look toward the bottom of the navigator pane and press the Plus button
This will allow you to manually add a breakpoint.
I selected a C++ breakpoint and entered the message name into the name text field.
after adding this exception it did in fact break.
However this may or may not be useful to you as an objective c developer. This broke into the Assembly code.
Unfortunately it only showed this point on the call stack for the thread.
And it turned out that the autorelease problem was because a class called autorelease in a dispatch_once call. and further investigation revealed that the +(void)load; method on the class was called before anything else. this is done via the call_load_methods function and is outside the thread on the main method.
to correct this, I merely added the autorelease pool wrapper around the call.
another solution may be to add the autorelease pool inside the +(void)load; method. but this was sufficient for my uses.
NOTE: I am adding this to the post here because I do not like finding an issue and not being able to figure out all paths to the resulting answer. If the debugger tells you to add a breakpoint to the function listed, then there should be some information somewhere to get that information. Hopefully this will lower the frustration of some of those out there trying to find this answer.
Many of the methods in the cocoa api return autoreleased objects. In particular, those methods that return an object that don't begin with init, such as [NSNumber numberWithLong:]. If you don't have an autorelease pool in place, those objects will be leaked. You can find more information on using NSAutoreleasePool in the documentation.
It means you need to create an autorelease pool on the thread it happens. Otherwise, your allocated objects will not be destroyed (as suggested by the message). So, break/pause at the symbol, then walk up the stack to your thread (or program) entry and add an autorelease pool. That's all.

scope of autorelease pool

Does NSAutoreleasePool also covers variables in all the called methods?
If that's the only place where -isNotExpired is called, the auto release pool you've set up will contain objects autoreleased in -isNotExpired (including startDate).
Note that in a normal Cocoa application, NSApplicationMain() called in main() in main.m will create an autorelease pool for you, so this code wouldn't leak anyway. You generally only create your own autorelease pool in cases where you'll be generating lots of temporary objects with a short useful life (in a loop for instance) and want to keep your high water memory usage down.

Using autoReleased objects without an NSAutoReleasePool?

I'm writing my very first steps in Objective-C.
I followed some examples and the official documentation, and am using autoreleased objects* without explicitly declaring an NSAutoReleasePool.
* By autoreleased objects I mean: SomeClass *obj = [SomeClass someClass];
Is it ok to do it this way?
Will it cause a memory problem?
Is declaring a NSAutoReleasePool more efficient?
edit: I made a mistake in the code example, what I meant was getting an object by it's class factory method instead of allocing an instance of it. This factory methods [often|always] return autoreleased objects, right? for example: [NSString stringWithCString:x]
You don't need to create an autorelease pool explicitly usually. When you do normal Mac programming using the AppKit framework, there will be an implicit autorelease pool which is handled by the event loop. You need to concern yourself with autorelease pools mainly on two occasions:
Your code runs in a background thread: If you have a background thread there is no autorelease pool created for you and you will have to do this manually.
You have a tight loop where you create and destroy a lot of objects. If in this loop any objects are autoreleased they will not actually be released until the autorelease pool is drained. This means that your memory consumption will rise, even though you don't reference those objects anymore. In this situation having a local autorelease pool can help with performance, although switching from autoreleasing to explicit retain/release is probably more efficient.
In answer to your question: that's a no-no. You will leak memory if you autorelease an object (or use an autoreleased object) in a scope that has no autorelease pool.
perhaps ignore the following:
With regard to your example, it might be rather confusing the way you've written it, since Class is a typedef of struct objc_class*. So, you're really declaring a pointer-to-a-pointer to a class, and then assigning a pointer to a class to it. Which won't work. Moreover, since Class is not an Objective-C “class-type” per se, you can't send messages to it.
But all this is neither here nor there, since ±class does not return an autoreleased object.