• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
NSAutoreleasePool Problem
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


  • Follow-Ups:
    • Re: NSAutoreleasePool Problem
      • From: Shawn Erickson <email@hidden>
    • Re: NSAutoreleasePool Problem
      • From: Shawn Erickson <email@hidden>
  • Prev by Date: Fake NSMenu-like view
  • Next by Date: Re: NSAutoreleasePool Problem
  • Previous by thread: Re: Fake NSMenu-like view
  • Next by thread: Re: NSAutoreleasePool Problem
  • Index(es):
    • Date
    • Thread