4

I have the problem in an iOS app that after some time, an object isn't dealloc'ed as it should be. I suspect that this is because there is still a reference to it. I'm using ARC.

I want to find out where that reference is created. I will then be able to tell where it should be NULLed or if it should be made a weak reference.

What I imagine as a possible solution:

If I could set a breakpoint for every place where the reference count, aka retain count, is modified, then I will be quick to find the problem. I just don't know how to set such a breakpoint. Maybe at pre-ARC times, this could have been done by setting breakpoints inside retain and release, but I have no idea how to do this with ARC.

Highly simplified example code:

I've done this in one of my classes and I know where:

// ShouldBeDeallocated.m

- (void) dealloc {
    NSLog(@"%s", __FUNCTION__); // this never shows up in output
}

And I suspect that I wrote code like this some time ago, but I can't find where that was:

// UnknownSuspect.m

@interface UnknownSuspect ()

@property (strong, readwrite) id referenceWhichIsNeverNeeded;

@end

- (void) someMethod:(ShouldBeDeallocated*)ref {
    self.referenceWhichIsNeverNeeded = ref;
    // The object pointed to by referenceWhichIsNeverNeeded will
    // not be dealloc'ed unless the property gets overwritten.
}
Daniel S.
  • 6,458
  • 4
  • 35
  • 78
  • I've checked all warnings of the static analyzer. I've also used Instruments to check for memory leaks. Most of the shown leaks say something about a few bytes in NSMutableDictionary or malloc. There, I did not find anything which I can relate to the code I wrote. – Daniel S. Feb 26 '14 at 17:46
  • 1
    My question might be a duplicate of http://stackoverflow.com/questions/6988911/finding-all-references-to-an-object-instance-in-obj-c . – Daniel S. Feb 27 '14 at 00:50
  • This question still didn't get an answer which I fully accept, but I solved my personal problem by reading manually through heaps of my code. Through this manual effort, I eventually found the culprit, a cyclic reference. Instruments does not detect this cyclic reference for some reason, although it is a very simple one. – Daniel S. Feb 27 '14 at 01:14

1 Answers1

1

You can use Instruments to profile memory allocations. Then you can see where in your code it is allocating it and changing the retain count. Instruments can also help track down where you have memory leaks in your code, which is still possible even with ARC.

Gavin
  • 8,204
  • 3
  • 32
  • 42
  • I still don't know how to spot a non-weak reference which is not released, e.g. a cyclic reference. I know that "Instruments can be used to spot memory leaks", but this is a way to broad hint. My problem is not the allocations, but that I'm keeping too many references at some later point. – Daniel S. Feb 26 '14 at 16:17
  • @DanielS. It's the first step to tracking down memory issues. You should be able to see where in your code your offending object is being retained and determine which other objects have references to it from that. Then you can see why those ones are being retained still as well. I don't think breakpoints in your code would be of much help, but analyzing what's going on with Instruments is the go-to place for memory leak issues. You should also use the static analyzer in Xcode to see if it sees any possible issues with your code that could result in memory leaks. – Gavin Feb 26 '14 at 16:23
  • I've checked all warnings of the static analyzer. I've also used Instruments to check for memory leaks. Most of the shown leaks say something about a few bytes in NSMutableDictionary or malloc. There, I did not find anything which I can relate to the code I wrote. Can Instruments detect a reference which I accidentally left over, but do not need anymore? – Daniel S. Feb 26 '14 at 17:02
  • @DanielS. You mean if for some reason an object is keeping a reference to another object but is never going to do anything with that reference? You can see that reference with Instruments when you look at the allocations information for the object, but it won't make it somehow "stand out" from the rest. It won't know that your legitimate reference is somehow not needed, or not needed any longer past a certain point. – Gavin Feb 26 '14 at 17:10
  • Yes, this is what I mean. How can I see this reference? - I go to Xcode > Product > Profile - then what? – Daniel S. Feb 26 '14 at 17:27
  • I've updated the question with code to show better what problem I have. – Daniel S. Feb 26 '14 at 17:37
  • Retain cycles are hard to debug using tools like Instruments. Does your `ShouldDealloc` instance by any chance retain a block in which is referred to `self`? Is `ShouldDealloc` the target of a repeating `NSTimer`, `NSThread`, or `CADisplayLink` instance, which it also retains? – datwelk Feb 26 '14 at 17:51
  • @datwelk: as far as I'm aware, it's only used in blocks passed to [UIView animateWithDuration:...], but not in any block which is retained. – Daniel S. Feb 26 '14 at 18:01
  • @Gavin I've just reread the comments and noted you wrote "You should be able to see where in your code your offending object is being retained and determine which other objects have references to it from that." - This sounds like what I need, but I couldn't find it in Instruments yet. Can you elaborate on this, please? – Daniel S. Feb 27 '14 at 00:45