What's up with UI interaction and NSMutableArray+NSAutoReleasePop()?
What's up with UI interaction and NSMutableArray+NSAutoReleasePop()?
- Subject: What's up with UI interaction and NSMutableArray+NSAutoReleasePop()?
- From: Jay Koutavas <email@hidden>
- Date: Sun, 20 Mar 2005 18:49:30 -0500
Hi.
My application uses NSURLHandle to periodically check the contents of an http page on a remote server. The application for the most part is faceless -- it's a cocoa application that just polls on this http page, over and over, in the background, for hours, sometimes days.
I am seeing a behavior of object releases within NSMutableArray that I don't understand. Objects I'm putting into a NSMUtableArray are getting deallocated only when I touch the menu bar -- if I leave my app just running without interacting with the UI in any way, my object deallocations don't occur. Very odd.
The attached code example is a distillation of my application. In this example, a "MyObject" is created every two seconds, added to the "sArray" NSMUtableArray and then the MyObject instance does a fetch of the remote http page. When the fetch completes, the MyObject instance is removed from sArray. It does remove properly, but the dealloc on the object occurs first somewhat latently, and later, not til the user interface is touched in some way (I usually touch the File Menu). I am able to see this with two NSLogs(), one in the MyObject init, and the other in the MyObject dealloc. Here's what the Console log looks like:
[Session started at 2005-03-20 18:39:47 -0500.]
2005-03-20 18:39:49.899 nsautoreleasepop_study[12877] created object 36b3d0. Count = 1
2005-03-20 18:39:50.328 nsautoreleasepop_study[12877] Data length = 4641
2005-03-20 18:39:51.899 nsautoreleasepop_study[12877] created object 36ce50. Count = 2
2005-03-20 18:39:52.127 nsautoreleasepop_study[12877] Data length = 4641
2005-03-20 18:39:53.899 nsautoreleasepop_study[12877] created object 36c0f0. Count = 3
2005-03-20 18:39:54.125 nsautoreleasepop_study[12877] Data length = 4641
2005-03-20 18:39:55.899 nsautoreleasepop_study[12877] created object 36dc50. Count = 4
2005-03-20 18:39:56.123 nsautoreleasepop_study[12877] Data length = 4641
2005-03-20 18:39:57.899 nsautoreleasepop_study[12877] created object 36d140. Count = 5
2005-03-20 18:39:58.654 nsautoreleasepop_study[12877] Data length = 4641
2005-03-20 18:39:59.899 nsautoreleasepop_study[12877] created object 36de30. Count = 6
2005-03-20 18:40:00.235 nsautoreleasepop_study[12877] Data length = 4641
2005-03-20 18:40:01.899 nsautoreleasepop_study[12877] created object 36cf20. Count = 7
2005-03-20 18:40:02.125 nsautoreleasepop_study[12877] Data length = 4641
2005-03-20 18:40:03.899 nsautoreleasepop_study[12877] created object 36f530. Count = 8
2005-03-20 18:40:04.130 nsautoreleasepop_study[12877] Data length = 4641
2005-03-20 18:40:05.899 nsautoreleasepop_study[12877] created object 36e470. Count = 9
2005-03-20 18:40:06.125 nsautoreleasepop_study[12877] Data length = 4641
2005-03-20 18:40:07.899 nsautoreleasepop_study[12877] created object 370590. Count = 10
2005-03-20 18:40:08.124 nsautoreleasepop_study[12877] Data length = 4641
2005-03-20 18:40:08.378 nsautoreleasepop_study[12877] dealloc object 370590. Count = 9 <-- right here I touch the menu bar.
2005-03-20 18:40:08.378 nsautoreleasepop_study[12877] dealloc object 36e470. Count = 8
2005-03-20 18:40:08.378 nsautoreleasepop_study[12877] dealloc object 36f530. Count = 7
2005-03-20 18:40:08.378 nsautoreleasepop_study[12877] dealloc object 36cf20. Count = 6
2005-03-20 18:40:08.378 nsautoreleasepop_study[12877] dealloc object 36de30. Count = 5
2005-03-20 18:40:08.379 nsautoreleasepop_study[12877] dealloc object 36d140. Count = 4
2005-03-20 18:40:08.379 nsautoreleasepop_study[12877] dealloc object 36dc50. Count = 3
2005-03-20 18:40:08.379 nsautoreleasepop_study[12877] dealloc object 36c0f0. Count = 2
2005-03-20 18:40:08.379 nsautoreleasepop_study[12877] dealloc object 36ce50. Count = 1
2005-03-20 18:40:08.379 nsautoreleasepop_study[12877] dealloc object 36b3d0. Count = 0
2005-03-20 18:40:11.899 nsautoreleasepop_study[12877] created object 390780. Count = 1
Essentially, when I touch the UI, NSAutoReleasePop() gets called and the deallocs "take". If I don't touch the UI, which is normal for my app not to touch the UI then these things never dealloc and I essentially have a memory leak.
What's happening here? Why does it take a UI interaction to dealloc these objects? How can I "force" these deallocs to occur programmatically?
Running this on Mac OS X 10.3.8.
Thank you for your help,
/Jay
Here's the code example, I basically created a new Cocoa app from Xcode and stuck my code into an instantiation of NSWindow, for sake of example.
===================================================================
static NSMutableArray* sArray = 0;
static unsigned sCount = 0;
@interface MyObject : NSObject <NSURLHandleClient>
- (void)fetch:(NSString*)urlString;
@end
@implementation MyObject
- (id)init {
if( self = [super init] ) {
sCount++;
NSLog(@"created object %x. Count = %d", self, sCount);
}
return self;
}
- (void)dealloc {
sCount--;
NSLog(@"dealloc object %x. Count = %d", self, sCount);
[super dealloc];
}
- (void)fetch:(NSString*)urlString {
NSURL* url = [NSURL URLWithString:urlString];
NSURLHandle* URLHandle = [url URLHandleUsingCache:NO];
[URLHandle addClient:self];
[URLHandle loadInBackground];
}
- (void)URLHandle:(NSURLHandle *)sender
resourceDataDidBecomeAvailable:(NSData *)newBytes {
// required to adhere to NSURLHandleClient protocol
}
- (void)URLHandleResourceDidBeginLoading:(NSURLHandle *)sender {
// required to adhere to NSURLHandleClient protocol
}
- (void)URLHandleResourceDidFinishLoading:(NSURLHandle *)sender {
NSData *data = [sender resourceData];
NSLog(@"Data length = %d", [data length]);
[sender removeClient:self]; // disconnect this from the URL handle
[sArray removeObject:self];
}
- (void)URLHandleResourceDidCancelLoading:(NSURLHandle *)sender {
NSLog(@"Content check was canceled.");
[sender removeClient:self]; // disconnect this from the URL handle
[sArray removeObject:self];
}
- (void)URLHandle:(NSURLHandle *)sender
resourceDidFailLoadingWithReason:(NSString *)reason {
NSLog(@"Content check failed. Reason is %@", reason);
[sender removeClient:self]; // disconnect this from the URL handle
[sArray removeObject:self];
}
@end
@implementation MyWindow
- (void)addObjectTask:(NSTimer*)timer {
MyObject* anObject = [MyObject new];
[sArray addObject:anObject];
[anObject release];
[anObject fetch:@"http://www.heynow.com"];
}
- (void)awakeFromNib {
sArray = [NSMutableArray new];
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self
selector:@selector(addObjectTask:) userInfo:0 repeats:YES];
}
@end
_______________________________________________
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