I've tried asking a couple people I know but they were probably too busy to give me at advice on this.
I keep running into walls with the way alloc/dealloc are dealt with. The following one is driving me nuts... this is a boiled down essence of some code I have been trying to debug all week.
Here is what I think should be happening (but obviously is not):
- I allocate a pool
- I create an object and autorelease to put it in the current pool so it will dealloc when I release the pool.
- The test class has an NSString var that is only internal.
- The NSString is released in the dealloc method of that class.
- I release the pool, which does try to release the test object,
- It segfaults in the dealloc method as soon as it tries to release the NSString.
In the past I've managed to get buy by fiddling until the problem went away. However I have now reached the point of development where I need to be able to prove I have eliminated storage issues.
I have read masses of documentation over the last year on ObjC storage management. Unfortunately, there seems to be some disagreement in how this all actually fits together, and that confusion is not helpful to those of us who have not been part of this managed storage process as it grew. If I am having difficulties (I used to write DSA's in assembly code for RTOS's), I can only imagine what others must be facing.
One thing that would be really useful is a manual on how to test your code to eliminate this sort of fault. I am sure such information exists, and have run across a bit here and a bit there, but the pieces don't all fit together neatly. I've also been using enableDoubleReleaseCheck.
I left it out to keep the test case simple.
Here's CommandTest.m, a complete test case that results in:
./CommandTest
Release cmdline
Segmentation fault (core dumped)
/* Makefile strings:
OBJC = gcc -g -fobjc-exceptions -fconstant-string-class=NSConstantString -D_NATIVE_OBJC_EXCEPTIONS -I /usr/include/GNUstep
CommandTest: CommandTest.o $(OBJC) -g -o CommandTest CommandTest.o -lobjc -lgnustep-base */
#include <stdio.h>
import
@interface Command:NSObject {NSString *cmdline;}
- (id) init;
- (void) dealloc;
@end
@implementation Command
- (id) init {
if (!(self = [super init])) {return nil;}
cmdline = [NSString stringWithCString: "This is a test"];
return self;
}
- (void) dealloc {
printf ("Release cmdline\n");
[cmdline release];
printf ("Release cmdline done\n");
[super dealloc];
}
@end
int main( int argc, char *argv[] ) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
Command *cmd = [[Command new] autorelease];
@try {[pool release];}
@catch (NSException *e){
printf ("Fatal [%s] %s\n", [[e name] cString], [[e reason] cString]);}
printf ("Done\n");
exit (EXIT_SUCCESS);
}
Advice would be most welcome and much appreciated.