Ios App With Arc, Find Who Is Owner of an Object

iOS app with ARC, find who is owner of an object


  1. In terms of the academic question of who "owns" an object, this is simply whomever maintains a strong reference to that object.

  2. In terms of finding leaks in your app, you can use the "Leaks" tool in Instruments when you profile the app (choose "Profile" on Xcode's "Product" menu).

  3. If it's not showing up in "Leaks", though, it seems like you then have to decide whether it is a strong reference cycle (formerly known as a retain cycle), some simple logic error (e.g. some circular reference in view controllers, caching large objects, etc.) or some Core Foundation related problem (ARC doesn't assume ownership unless you're careful about using CFBridgingRelease() or __bridge_transfer).

  4. In terms of using Instruments to find the source of the allocations, the two tricks that help me the most are:

    • Click in drag with your mouse (in Xcode versions prior to 6, you have to hold the option key while you do this) to highlight a portion of the timeline, to identify what you want to inspect. You probably want to focus on one of your spikes in allocations. For example, I found a bump in my allocations and highlighted it as such (this was a ludicrously simple example where I create a huge array in viewDidLoad, but hopefully it give you the idea):

    iOS Sample Image 11

    • When you inspect by call tree, it's often useful to select "Hide System Libraries", to focus on your code. And if you double click on the method name in Instruments (in my example, here, it would be viewDidLoad), Instruments will then show you your code that's doing the allocation:

    iOS Sample Image 12

    You can then double click on the relevant method listing and it will take you precisely to the code that did the allocation.

    iOS Sample Image 13

While this doesn't show you were the leak took place (i.e. where the strong reference cycle or where you failed to release it), but this sort of analysis can often help you track down where the leaked object was instantiated, which is the first step to tracking down the problem.


If you really must figure out who "owns" an object (i.e. where the object's strong references (or retains) occurred), Xcode 8 has a new object graph feature. So debug the app and then tap the "Debug Memory Graph" icon in the debug bar (circled in red, below). Once you do that you can select an object on the left and you can see the object graph that shows claims of ownership on the object:

iOS Sample Image 14

The above illustrates that the chosen image is has strong references by both the UIImageView in which it is presented, but also the ViewController is maintaining a strong reference, too.

In earlier Xcode versions, profile the app to run it through Instruments and select the "Record reference counts" option. In Xcode 6, this is located on "Record settings" tab in the right most panel:

iOS Sample Image 15

In Xcode 5 and earlier, you have to click on the i info button next to the Allocations tool to see this "Record reference counts" option:

Sample Image

Anyway, you can then go to the Allocations Summary, drill into some object that wasn't released, (by clicking on the right arrow arrow next to the object address when looking at and object in Allocations tool), and then you'll see the list of retains and releases for the object in question, as shown above. But this only will be captured if you select the "Record reference counts" before profiling the app.

It takes a while to get used to tracking retain counts this way, but if you absolutely need to know where the strong references were established, the "Record reference counts" option can help you out.

Print strong owners of an object , Swift

No there is not a way to print the owners of an object as you describe, at least not exactly. iOS does not use garbage collection, it uses ARC (Automatic Reference Counting.) The system doesn't track owning references in ARC. Instead, each time you add an owning reference to an object the system increases a retain count, and every time you clear an owning reference the system decrements that retain count.

What you can do, though, is run your program with the memory instrument. (There is a debugging application called "Instruments", you pick a debugging template called an "instrument" that you use within the Instruments program.) With the memory instrument you can follow the life-cycle of an object, as well as tracking the number of active objects in your app's heap.. When you select an object in the list of currently active object you can see where in your program it was allocated and where the code that creates strong references comes from. Explaining how to use Instruments is beyond the scope of an SO post however. There are various tutorials and WWDC session videos on the subject. I suggest doing some searching.

As to your question, forcing a low memory warning would not cause an active view controller (one that is on-screen) to be released and it's deinit method to be called. The system maintains a strong reference to the view controller.

Also, you should make delegate references weak by default. Having a delegate reference be a strong reference is VERY unusual. I've only seen it once or twice, for specific reasons.

What is the owner of UI elements of a view controller? iOS5 with ARC

In my opinion you can consider the NIB/XIB as the owner of those objects. None of your classes own them. See "Managing the Lifetimes of Objects from Nib Files" in Resource Programming Guide:

From a practical perspective, in iOS and OS X outlets should be defined as declared properties. Outlets should generally be weak, except for those from File's Owner to top-level objects in a nib file (or, in iOS, a storyboard scene) which should be strong. Outlets that you create should will therefore typically be weak by default, because:

  • Outlets that you create to, for example, subviews of a view controller's view or a window controller's window, are arbitrary references between objects that do not imply ownership.
  • The strong outlets are frequently specified by framework classes (for example, UIViewController's view outlet, or NSWindowController's window outlet).

Using the debugger to find all strong references to an object

Yes, using Instruments.app, you can. Apple has a simple introduction, and if that doesn't help, many others have tutorials for using Instruments as well.


edit - this article looks useful, too.

How do I verify reference count in ARC mode?

You can use CFGetRetainCount with Objective-C objects, even under ARC:

NSLog(@"Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)myObject));

This is not particularly useful for debugging, though, for reasons amply described elsewhere. If you need to understand where an object is being retained and released, check out this answer for help using the Allocations instrument.

The only case I've found where examining the retain count is actually useful is in a dealloc method, when something retains and autoreleases the object being deallocated. This will cause a crash later when the autorelease pool is drained. You can pinpoint the cause of this by checking the retain count before and after each message. In this way I discovered that the observationInfo method (which is itself usually only useful for debugging) retains and autoreleases self. However, even this sort of problem can usually be solved without examining the retain count, simply by wrapping the entire body of dealloc in an @autoreleasepool block.

However, the retain count can be used to learn about the implementation of some classes. (Only do this for entertainment or curiosity! Never rely on undocumented implementation details in production code!)

For example, try this immediately inside the @autoreleasepool in main:

NSNumber *n0 = [[NSNumber alloc] initWithInt:0];
NSLog(@"0 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef)n0));
// Prints 2 in my test

So NSNumber likely caches (or at least reuses) some instances. But not others:

n0 = [[NSNumber alloc] initWithInt:200];
NSLog(@"n0 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n0));
// Prints 1 - I am the sole owner of this instance. There could be weak
// or unretained references to it, but no other strong references.

NSNumber *n1 = [[NSNumber alloc] initWithInt:200];
NSLog(@"n1 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n1));
// Prints 1 again. New instance with same value as prior instance.
// You could of course compare pointers to see that they are separate
// instances.

You can even discover that NSNumber returns a singleton if you alloc but don't initialize:

n1 = [NSNumber alloc];
NSLog(@"n1 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n1));
// Prints -1.

(Note that you can also learn many details about NSNumber by looking at the Core Foundation source code, which is available at http://opensource.apple.com. But who knows what you might find if you look at the retain count of objects that aren't toll-free-bridged with objects in Core Foundation?)

Why is object not dealloc'ed when using ARC + NSZombieEnabled

Turns out it is an iOS bug. Apple has contacted me and indicated they've fixed this in iOS 6.

So what's the deal with ARC and releasing properties/subviews on viewDidUnload

So each view has a number of owners. When that "owner count" (usually referred to as the retainCount) reaches 0, that object gets destroyed.

In iOS 5, we now have weak references, which essentially means "don't own this object".

Before iOS 5, in our header files, you'd see

IBOutlet UILabel *myLabel;

And this label was added to the XIB file's view. myLabel has 2 owners in this case: it's superview (the view in the XIB file) and the view controller (by having the IBOutlet). When viewDidUnload get's called, the view controller's view has been released, and therefore it's ownership of myLabel is gone. So myLabel at this point only has 1 owner, the view controller. So we needed to release it in viewDidLoad to make sure it didn't have any owners and so was destroyed.

With iOS 5, you will often seen this instead

__weak IBOutlet UILabel *myLabel

This is saying that we don't want the view controller to be an owner of myLabel. So the only owner is the view controller's view. So when viewDidUnload get's called, the view controller's view has already been released, and so its ownership of myLabel has also been released. In this case, myLabel now has no owners and its memory is released. There is no need for the self.myLabel = nil; there.

So with iOS 5, the recommendation is to make all of your IBOutlets a weak reference. With this, you don't even need to implement viewDidUnload, as all the memory has been taken care of for you.

But even if you are using iOS 5, if your IBOutlets aren't weak references, you'll need that code in viewDidUnload.

Objective-C reference count when pointer set to nil (without ARC)

No. If you're not using ARC, the object is released when you call [obj release];. (ARC inserts these calls for you.) Setting obj to nil does nothing in terms of memory management (although it does create an object you can no longer reach!).

Basically, in Cocoa without ARC:

  • You call [obj retain] if you want to take ownership of an object. (alloc does this for you.)
  • You call [obj release] when you want to relinquish ownership of an object. release in turn calls dealloc when the object's retain count reaches 0.
  • You call [obj autorelease] when you want to relinquish ownership of an object outside of its current scope. Most commonly, this happens when you return an object from a method (and don't want to retain ownership of it).

When ARC is triggered in the lifecycle of an iOS app?


  1. Its already answered here, the first view controller will not be deallocated if it pushes/presents another controller.
  2. If iOS kills your app, all the memory holds by your app will be released. So next when you open your app, it will be a fresh launch. And there is something called memory warnings, when device running out of memory or your app consumes lot of memory OS will send out memory warnings. Implement the didReceiveMemoryWarning method and release any un used data or resources. It may save your app from killing by the OS.


Related Topics



Leave a reply



Submit