NSAutoreleasePool Problem
NSAutoreleasePool Problem
- Subject: NSAutoreleasePool Problem
- From: Matthew Miller <email@hidden>
- Date: Sun, 29 Jan 2006 16:17:30 -0500
Hi All -
New to the Cocoa development environment (and Objective-C for that
matter) and I'm curious. If you write a simple app that creates two
instances of NSNumber as follows, you'll get the same address space.
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// insert code here...
NSLog(@"Hello, World!");
NSNumber *test = [[NSNumber alloc] initWithInt:10];
NSNumber *test2 = [[NSNumber alloc] initWithInt:10];
printf("%d (%d)\n", [test intValue], [test retainCount]);
printf("%d (%d)\n", [test2 intValue], [test2 retainCount]);
[test release];
[test2 release];
[pool release];
return 0;
}
The output looks like this:
[Session started at 2006-01-29 13:48:10 -0500.]
2006-01-29 13:48:10.578 ArrayWithRetainProb[362] Hello, World!
10 (3)
10 (3)
ArrayWithRetainProb has exited with status 0.
Obviously, I'm missing something but I thought that alloc would work
like new in C++ and assign a new address. BTW, this doesn't seem to
happen when you use NSString. So I'm confused there.
I'm having trouble with another program that involves retrieving data
from a MySQL database using the MySQL C API and I'm trying to wrap
those functions in a class that returns an instance of a custom class
(really just an NSArray with some ints for rows and cols). The
program logic works fine but when I run the test program, it gives me
a SIGTRAP on a call to [pool release] (in the method
NSPopAutorelease). I thought this would probably has to do with
releasing an item that is then undefined when the NSAutoreleasePool
is cleaning up. So I looked at the data coming back and the code.
The query returns several fields with a value of 1 or 0 (for fields
defined as a TINYINT). When I run the code with similar debugging
comments to give me reference counts on items that are, effectively,
the number of rows multiplied by the number of 0s (or 1s) (e.g. 100
rows with 3 0's per row is retainCount of 301 for the last field
value of 0 in the last row). That tells me that Objective-C is doing
something weird with the data. Here is the code that places the
items into the custom class:
while((row = mysql_fetch_row(r)) != NULL)
{
unsigned long *lengths;
lengths = mysql_fetch_lengths(r);
for(i = 0; i < numfields; i++)
{
if(row[i])
{
char *buf = malloc(((int)lengths[i] * sizeof(char)) + 1);
memcpy(buf, row[i], (int)lengths[i]);
buf[(int)lengths[i]] = '\0';
field = (MYSQL_FIELD *)[[fields objectAtIndex:i] pointerValue];
switch(field->type)
{
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_SHORT:
[qr addInt:atoi(buf)];
break;
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_LONGLONG:
[qr addLong:atol(buf)];
break;
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
[qr addFloat:atof(buf)];
break;
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_SET:
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_GEOMETRY:
case MYSQL_TYPE_NULL:
[qr addNull];
break;
default:
[qr addCString:buf];
break;
}
free(buf);
} else {
// place NULL into collection
[qr addNull];
}
}
}
// do we need to get each field * and free that memory? Or is it
handled by
// the freeing of the result?
[fields release];
mysql_free_result(r);
// [self setInUse:NO];
return qr;
And here is the code within the class that transfers the data:
- (BOOL)addInt:(int)__value
{
NSNumber *num = [[NSNumber alloc] initWithInt:__value];
[_data addObject:num];
NSLog(@"%d has %d refs", [_data count], [[_data objectAtIndex:[_data
count] - 1] retainCount]);
[num release];
return YES;
}
- (BOOL)addLong:(long)__value
{
NSNumber *num = [[NSNumber alloc] initWithLong:__value];
[_data addObject:num];
NSLog(@"%d has %d refs", [_data count], [[_data objectAtIndex:[_data
count] - 1] retainCount]);
[num release];
return YES;
}
- (BOOL)addFloat:(float)__value
{
NSNumber *num = [[NSNumber alloc] initWithFloat:__value];
[_data addObject:num];
NSLog(@"%d has %d refs", [_data count], [[_data objectAtIndex:[_data
count] - 1] retainCount]);
[num release];
return YES;
}
- (BOOL)addCString:(const char*)__value
{
NSString *str = [[NSString alloc] initWithUTF8String:__value];
[_data addObject:str];
NSLog(@"%d has %d refs", [_data count], [[_data objectAtIndex:[_data
count] - 1] retainCount]);
[str release];
return YES;
}
Any thoughts? I'm stuck and I don't want to just let the
NSAutoreleasePool crash every time I run the program.
Thanks,
Matt
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden