Unjustified CPU load with a simple Document .app
Unjustified CPU load with a simple Document .app
- Subject: Unjustified CPU load with a simple Document .app
- From: ettore <email@hidden>
- Date: Fri, 06 Jun 2003 18:30:21 -0700
Hello, I'm learning cocoa and I made a simple Document app called SimpleTimer which starts an NSTimer and prints a message on the console when the timer ends. My project is composed by the MyDocument class, its Nib and the MainMenu.nib which is untouched. The GUI has
- 2 TextFields: "minutes to wait" and the "message" to be displayed.
- 2 buttons: "Start" and "Invalidate": "Start" creates the NSTimer and "Invalidate" calls the `invalidate:' method of NSTimer.
MyDocument has a NSTimer, a NSMutableDictionary for saving the data of the timer document, and the UI outlets. MyDocument is the delegate of the 2 NSTextFields, and it implements
-(BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor.
It also implements the method the NSTimer will fire when it finishes counting.
Everything works except for one fact: when a document is open, and SimpleTimer is the active application (i.e. its menus are visible on the menubar at the top of the screen) I notice - with `top' from the terminal - a big CPU load (20%-30%) related to SimpleTimer, even when the NSTimer object is not allocated and the mouse is not moving. If I close all the documents (not the app), or either click on some other application, the SimpleTimer load drops to 0. I tried to remove the NSTimer, the delegate method and the MutableDictionary from the class with no effect. I know `top' is not reliable, but I can't understand why my trivial application has a load of 30% while every other application has a load of 0. BTW, my app is very similar (if not identical) in the structure to Hillegaas' `RaiseMen.app' listed in his book `Cocoa Programming with Mac OS X', but of course his application doesn't have my issue.
Any help would be greatly appreciated. I used OS X 10.2.6, PB 2.0.1 (July 2002
Dev Tools), IB 2.3.1 (v286). Thanks in advance.
Ettore
//
// MyDocument.h
//
#import <Cocoa/Cocoa.h>
extern NSString *CLTimerAmount;
extern NSString *CLTimerMsg;
@interface MyDocument : NSDocument
{
// outlets
IBOutlet NSTextField *timeField;
IBOutlet NSTextField *msgField;
IBOutlet NSButton *startButton;
IBOutlet NSButton *invalidateButton;
// private vars
NSTimer *timer;
NSMutableDictionary *timerModel;
}
// actions
- (IBAction) startTimer:(id)sender;
- (IBAction) invalidateTimer:(id)sender;
// private methods
- (void) openPanelWithTimer:(NSTimer *)aTimer;
- (NSString *) firingSel;
- (void) updateUI;
// delegate methods
- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor;
@end
//
// MyDocument.m
//
#import "MyDocument.h"
NSString *CLTimerAmount = @"CLTimerAmount";
NSString *CLTimerMsg = @"CLTimerMsg";
@implementation MyDocument
- (id)init
{
if (self = [super init]) {
timerModel = [[NSMutableDictionary alloc] init];
[timerModel setObject:[NSNumber numberWithDouble:1.0] forKey:CLTimerAmount];
[timerModel setObject:@"The time has come." forKey:CLTimerMsg];
}
return self;
}
- (void)dealloc
{
if (timer) [timer release];
[timerModel release];
[super dealloc];
}
// ************************************************
// DELEGATE METHODS: MyDocument is the delegate for the text fields
// ************************************************
- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor
{
[timerModel setObject:[NSNumber numberWithDouble:[timeField doubleValue]]
forKey:CLTimerAmount];
[timerModel setObject:[msgField stringValue] forKey:CLTimerMsg];
[self updateChangeCount:NSChangeDone]; //sets the doc. in a "To be saved" state
return YES;
}
// ************************************************
// ACTION METHODS
// ************************************************
- (IBAction) startTimer:(id)sender
{
double seconds;
SEL fsel = NSSelectorFromString([self firingSel]);
seconds = [timeField doubleValue] * 60;
if (timer) [timer release];
timer = [NSTimer scheduledTimerWithTimeInterval:seconds
target:self
selector:fsel
userInfo:@"my userinfo"
repeats:NO ];
[timer retain]; // otherwise it's a temporary object !
[invalidateButton setEnabled:YES];
[startButton setEnabled:NO];
}
- (IBAction) invalidateTimer:(id)sender
{
if (timer
&& [timer isValid]) {
[timer invalidate];
[invalidateButton setEnabled:NO];
[startButton setEnabled:YES];
}
}
// ************************************************
// LOAD AND SAVE METHODS
// ************************************************
- (NSData *)dataRepresentationOfType:(NSString *)aType
{
return [NSArchiver archivedDataWithRootObject:timerModel];
}
- (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType
{
NSLog(@"opening data....");
[timerModel release];
timerModel = [[NSUnarchiver unarchiveObjectWith
Data:data] retain];
[self updateUI];
NSLog(@"....data opened.");
return YES;
}
// ************************************************
// other stuff
// ************************************************
/* this method returns the name of the method to call when the timer fires*/
- (NSString *) firingSel
{
return @"openPanelWithTimer:";
}
/* this is a possible "fireable" method */
- (void)openPanelWithTimer:(NSTimer *)aTimer
{
[invalidateButton setEnabled:NO];
[startButton setEnabled:YES];
NSLog(@"timer: %@", timer);
NSLog(@"timer retain count: %d", [timer retainCount]);
}
/* update the UI with the values stored in the data model */
- (void) updateUI
{
[timeField setDoubleValue:[[timerModel objectForKey:CLTimerAmount] doubleValue]];
[msgField setStringValue:[timerModel objectForKey:CLTimerMsg]];
}
- (NSString *)windowNibName
{
return @"MyDocument";
}
- (void)windowControllerDidLoadNib:(NSWindowController *) aController
{
[super windowControllerDidLoadNib:aController];
[self updateUI];
}
@end
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.