how to find objects with autorelease message? - objective-c

My application crashes when the autorelease pool is released. The reason seems to be that the object with autorelease message is sent a release message sometime before the pool is released, hence the application crashes for object which is already released.
Hence I want to find which objects have a pending autorelease message, so that I can balance the retain .. release/autorelease messages to that object

if you dont know about 'NSZombieEnabled' you definitely need to check it out - Instructions are here
It won't tell you which objects are in the autoreleasepool but it will tell you which objects are being over-released.
In brief:
1)Double-click an executable in the Executables group of your Xcode project.
2)Click the Arguments tab.
3)In the "Variables to be set in the environment:" section, make a variable called "NSZombieEnabled" and set its value to "YES".

Related

Why do I need to remove a notification observer before the object I'm observing is deallocated?

From https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/Reference/Reference.html:
You must invoke removeObserver: or removeObserver:name:object: before any object specified by
addObserverForName:object:queue:usingBlock: is deallocated
Why does it matter that I stop observing before the object whose notifications I'm observing is deallocated? I understand why I as the observer need to stop observing if I'm going to disappear and the block depends on my existence, but I don't understand why the lifetime of the observed object matters. Am I misinterpreting this?
I understand why I as the observer need to stop observing if I'm going to disappear and the block depends on my existence, but I don't understand why the lifetime of the observed object matters.
I think that a possible explanation is the following.
addObserverForName:object:queue:usingBlock description says:
Adds an entry to the receiver’s dispatch table with a notification queue and a block to add to the queue, and optional criteria: notification name and sender.
"sender" in this context is just another name for the object parameter, which is described in the following terms:
The object whose notifications you want to add the block to the operation queue.
If you pass nil, the notification center doesn’t use a notification’s sender to decide whether to add the block to the operation queue.
So, object acts as a sort of filter: when a notification comes in, the notification center decides based on that value (if present) if the block must be added to the specified operation queue.
Now, consider this:
the observed object is deallocated without the observer to be removed;
a different object, also able to post notifications is created, and it happens it has the same address as the object deallocated at point 1;
now the observer will react to notifications posted by the second object.
I admit it is a pretty rare case, but it might happen, so you better code against it.
If u don't remove observer, it may leed to a situation when you already destroyed an object but it is still sent notifications - this will cause "message sent to deallocated instance" error

Getting -[CFURL retain] crash?

I am getting below crash on console
-[CFURL retain]: message sent to deallocated instance 0x691edc0
I am sending one videourl to another view to play video in MPMovieplayer. any idea.. Thanks
Your question is high-level. At a similarly high level: Run with Zombies enabled in Instruments. When you reproduce the error, find the zombie object, and review its reference count history/actions to determine where the imbalance was introduced.

Autorelease pools in Objective-C - release main AutoreleasePool?

By my understanding, when an object is sent an autorelease message, if no autorelease pools exist other than the one in main.m, the object gets placed in the one in main.m. Assuming this is correct, I have a couple of questions:
1) Do all autoreleased objects stay in that pool until the termination of the app?
2) If 1 is true, does creating an autoreleased object without a local autorelease pool (therefore placing that object in the main.m pool) keep that object in memory until termination of the app or a memory warning is received?
3) When is the main.m autorelease pool drained, other than when the app receives a memory warning or the application is terminated?
For example, in a cellForRowAtIndexPath delegate method such as this:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Foobar"];
if (cell == nil) {
// No cell to reuse => create a new one
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"Foobar"] autorelease];
// lots of custom stuff
}
return cell;
when are the cells actually released? They have to be autoreleased, because you can't release them before you return them, and you can't release them after, because they are out of scope. By my current understanding, the cells are placed in the topmost autorelease pool, and released when that pool is drained/released. In this case, that would be the only autorelease pool in the application; the one in main.
4) The problem with this it that even when I am done with those cells and the view controller has been released, the cells stay in memory, yes? If this is not the case, could someone provide an explanation of how the memory management in this situation really works? Thanks!
Note: I have looked at Apple's documentation, but it talks mostly about when to use your own local autorelease pools, but not much about how they actually function.
From the documentation:
The Application Kit creates an autorelease pool on the main thread at the beginning of every cycle of the event loop, and drains it at the end, thereby releasing any autoreleased objects generated while processing an event. If you use the Application Kit, you therefore typically don’t have to create your own pools. If your application creates a lot of temporary autoreleased objects within the event loop, however, it may be beneficial to create “local” autorelease pools to help to minimize the peak memory footprint.
So, autoreleased objects in the default pool will only survive the duration of the current event.
1) Do all autoreleased objects stay in that pool until the termination of the app?
Autoreleased objects by definition are owned by their autorelease pool until that pool is drained. When you send -autorelease to an object, that object is added to a list of objects that the pool will release later. Autorelease pools are organized in a stack, with the pool at the top of the stack being the pool to which any objects sent -autorelease are added. The pool created in main() is generally not the one at the top of the stack. For example, the run loop will create an autorelease pool at the beginning of each iteration.
2) If 1 is true, does creating an autoreleased object without a local
autorelease pool (therefore placing that object in the main.m pool)
keep that object in memory until termination of the app or a memory
warning is received?
It would if the pool created in main() were the topmost pool, but as described above, that usually won't be the case.
3) When is the main.m autorelease pool drained, other than when the
app receives a memory warning or the application is terminated?
There's no difference between the pool created in main() and any other autorelease pool. They're all drained when the pool is released, or at the end of the block if you used the #autorelease directive.

What is the correct way to release a GCD dispatch queue property?

I'm using a dispatch_queue which is accessed through a property of its owner, like this:
#property (nonatomic, assign) dispatch_queue_t queue;
Note the assign keyword. The queue is used throughout the objects life and thus owned by the object. I release the queue when the owning object is deallocated:
-(void)dealloc
{
dispatch_release(self.queue);
self.queue = nil;
}
How do I properly release this? Would using retain/release work?
What happens if there is stuff pending/running on the queue while calling release?
The following is stolen from the developer documentation:
Dispatch queues and other dispatch
objects are reference-counted data
types. When you create a serial
dispatch queue, it has an initial
reference count of 1. You can use the
dispatch_retain and dispatch_release
functions to increment and decrement
that reference count as needed. When
the reference count of a queue reaches
zero, the system asynchronously
deallocates the queue.
When your application no longer needs
the dispatch queue, it should release
it with the dispatch_release function.
Any pending blocks submitted to a
queue hold a reference to that queue,
so the queue is not deallocated until
all pending blocks have completed.
Note: You do not need to retain or
release any of the global dispatch
queues, including the concurrent
dispatch queues or the main dispatch
queue. Any attempts to retain or
release the queues are ignored.
So anywhere you would use -retain use dispatch_retain and anywhere you would use -release use dispatch_release.
Dispatch queues follow the same general memory management conventions as objective-c objects. And they won't be dealloc'ed until all blocks queued are finished.
If you do want a way to shut down a dispatch queue: There's no way to cancel all enqueued blocks via any sort of API, so they always must run to completion. One way to expedite this process is to have a BOOL variable in the class managing the dispatch queue: _isValid. When you want to shut down the queue, you can set _isValid to NO. All blocks submitted to the queue should first check _isValid before doing any work.
A side comment: It may be more appropriate to use NSOperationQueue. See Chris Hanson's blog post.
One interesting thing about this is that if the blocks submitted to the queue reference the object that owns the queue (e.g. "self"), the object will not hit dealloc until all pending blocks in the queue are completed anyway.
Here is a project that demonstrates this:
https://github.com/joshrl/GDCQueueDeallocTest
What happens if there is stuff
pending/running on the queue while
calling release?
It is safe. pending/running queue is retained from system. Calling dispatch_release just affects the retain count of the queue. See man page of dispatch_async or so forth.
setup your property like so:
#property (readwrite, strong, nonatomic) __attribute__((NSObject)) dispatch_queue_t queue;
Assign is implied and Strong will retain the queue telling ARC to treat it as an NSObject.

When is an object with 'autorelease' released?

I'm developing for iPhone, objective-c. When we use autorelease, when does the object actually get released - when the main autorelease pool gets released (ie. the application terminates?), or as soon as the local function ends? For example, I want to do something like this:
- (void) test
{
MyObj* p = [[[MyObj alloc] init] autorelease];
...
// is p 'released' here?
}
So is 'p' released as soon as the function exits, or when the autorelease pool of this thread is released? I thought it was when the local function exits, but I just created my own thread and needed to setup an autorelease pool which is giving me second thoughts on when this actually happens..
Thanks
An autoreleases object is released the same time the autorelease pool is. So for your thread it will be released when you release the pool. In the main thread, if you don't create your own, I believe the autorelease pool is drained every time through the run loop -- but I haven't looked at in a while.
As Argothian says, it is released when the autorelease pool is released, which happens every time through the run loop in a normal Cocoa application, not at application termination (unless of course you don't have a run loop, in which case you have to create the autorelease pool, and release it yourself). Autorelease pools don't know about each individual function call, and so could not release things at the end of a function call.