Leaks report seemingly unrelated issues
I am new to Cocoa and Objective-C. I am currently developing a fairly basic application to test my knowledge and put some things that I have read in practice. Everything works, but Leaks reports on a number of issues.
None of these leaks seem to apply directly to the code I wrote (I've read and tried to follow Apple's guidelines for memory allocation). Currently my project is using garbage collection and I am developing on Snow Leopard. Executing AnalysisTool shows no problems with my code (other than a few conventions warnings).
My application is currently using an NSTableView which I have connected to an NSArrayController. Interaction with NSTableView seems to cause leaks to report problems (actions such as sorting table columns and other standard user interactions). This leads me to believe that my use of the NSArrayController (and my implementation of its content source) is at fault.
Currently NSArrayController gets its content from NSMutableArray (timers), processed in my application debit like this:
- (id) init
{
if (self = [super init])
{
timers = [NSMutableArray array];
}
return self;
}
- (void) dealloc
{
[timers release];
[super dealloc];
}
Inside Interface Builder, my NSArrayController has its Object Controller set to the Timing class, which is defined below:
@interface Timing : NSObject {
NSString *desc;
NSDate *timestamp;
bool active;
}
@end
@implementation Timing
-(id) init
{
if (self = [super init])
{
desc = @"New timing";
timestamp = [[NSDate alloc] init];
active = false;
}
return self;
}
-(void) dealloc
{
[timestamp release];
[super dealloc];
}
@end
I've used Cocoa's standard bindings to hook up the add and remove buttons to control the TableView and they seem to work correctly (clicking the Add button creates a row in the TableView with the value "New timing", for example).
The leaks report that AppKit and CoreGraphics are responsible for the libraries. Although, to be honest, I'm still new to the Leaks tool, so I might be reading its output incorrectly. If that helps, I've posted a screenshot of my output here . If anyone could point me in the right direction it would really be appreciated.
As an aside, I've also experimented with manually adding objects to the timer array without using Cocoa bindings. This is what I came up with:
Timing *timingInstance = [[Timing alloc] init];
[timers addObject:timingInstance];
[timingInstance release];
[timersController setContent:timers];
[timersTableView reloadData];
Again this seems to work, but I thought I'd better ask the experts!
a source to share
Memory management for an array is timers
not entirely correct. Using the array
factory method returns an instance NSMutableArray
that has already been auto-implemented, so the lifetime of this object is (possibly) limited to the end of the current loop, and will be overfilled when you call release
your dealloc method. The correct way to do it is:
- (id) init
{
if (self = [super init])
{
timers = [[NSMutableArray alloc] initWithCapacity:0];
}
return self;
}
This method will give you an instance NSMutableArray
with a hold number of 1, which will then drop to zero (and deallocate memory correctly) when you call release
your dealloc method. The call alloc
in your method is init
balanced by the call release
in your method dealloc
. I noticed that this is the exact pattern you used for your object NSDate
in the class Timing
, so you are already familiar with the idea.
a source to share
Your code is not leaking as written. The Cocoa framework sometimes generates false reports of leaks when launching a pod leaks
, as some of the things like singlets and caches that are used when implementing frameworks are sometimes found to be leaks, even if they are not.
You are probably better off not using the ObjectAlloc and / or ObjectGraph tools to get an idea of when your objects are allocated and deallocated.
a source to share
My project is currently using Garbage Collection and I am developing on Snow Leopard
I do not understand. Are you using garbage collection? If so, then the GC will take care of releasing the objects for you, so wherever you use "release" absolutely nothing is done. When GC is enabled, Release calls are ignored. You only use release when you manage memory yourself when GC is off. Also, your dealloc methods don't do anything. This method is never used in GC. When you create an object and then finish it, you tell the GC that it is okay to get rid of the object by setting it to zero. That's all you need. No "deallocation" or dealloc method is required. Just install zero or unnecessary things.
a source to share