A couple xCode questions

Joined
Mar 4, 2010
Messages
51
Reaction score
0
Points
6
Hey.

I'm new to xCode but learning fast due to already having somewhat of a background in C++.
The whole square bracket/message thing was a little disconcerting at first, but I got used to it.

Anyways, on to my questions. There's two of them.

One:

I'm writing a little practice app for Mac osx that's supposed to allow you to set a timer and
then show a reminder message when the time runs out:



The slider is used to select # of minutes to set, the level indicator drains as time runs out, and the label
that says "1" changes to show number of minutes selected on the slider (not time remaining). Right now I'm
using a repeating NSTimer to tick seconds down. However, when the computer goes to sleep,
the NSTimer obviously stops repeating until the computer awakens.

I figure I need an NSDate set to x amount of seconds in the future (using dateWithTimeIntervalSinceNow)
but being that the user can press start and stop whenever they want, however many times they want,
they're going to be creating many NSDate's. When creating a new NSDate, do I just release the old one
by calling [endTime release] and then calling the above method again to create the next timer?
(assuming of course I already have an NSDate object named endTime)

Two:

I original wanted my slider on the above program to go from 1-240, and multiply the amount chosen
by 0.25 thus allowing them to choose from 1-60 minutes in 15 second increments. But as mentioned,
I also have a label on which I'm displaying the value of the slider.

I got the takeIntValueFrom thing down (by that I mean I control+clicked and dragged from the slider
to the textbox, and chose that method), but if the slider is 1-240, the label can also show 1 to 240.
How can I get it to multiply the slider value by 0.25 and show THAT on the label in real time
(thus still only showing 1-60?
 
Joined
Jun 25, 2005
Messages
3,231
Reaction score
112
Points
63
Location
On the road
Your Mac's Specs
2011 MBP, i7, 16GB RAM, MBP 2.16Ghz Core Duo, 2GB ram, Dual 867Mhz MDD, 1.75GB ram, ATI 9800 Pro vid
I did a similar little project a few years for the same reason, for practice. :) Mine takes manual input of the time interval of interest, so I didn't play with the slider technique.

From how I understand your description in question 1, I think you are on the right track. Give it a try.

For number 2, things get a little complicated to explain. I think this is what you want to know...

After you have done takeIntValueFrom in your action you have to apply your math. From the looks of my code, I converted the input of days, hours, minutes and seconds down to seconds. So do what it takes to convert a number such as 59.75 (239 * .25) minutes into seconds and use the value to calculate your endTime. Also use this value to set the textbox using setFloatValue:, I think.

If you want the textbox to have pretty formatting, you'll need to split the minutes and seconds out as separate numbers I think and setup an appropriate looking string. Although there maybe some formatting options I'm not aware of.

Someone at the Lake Forest CA Cocoaheads meeting last night was asking about this kind of app too.
 
OP
S
Joined
Mar 4, 2010
Messages
51
Reaction score
0
Points
6
I did a similar little project a few years for the same reason, for practice. :) Mine takes manual input of the time interval of interest, so I didn't play with the slider technique.

From how I understand your description in question 1, I think you are on the right track. Give it a try.

For number 2, things get a little complicated to explain. I think this is what you want to know...

After you have done takeIntValueFrom in your action you have to apply your math. From the looks of my code, I converted the input of days, hours, minutes and seconds down to seconds. So do what it takes to convert a number such as 59.75 (239 * .25) minutes into seconds and use the value to calculate your endTime. Also use this value to set the textbox using setFloatValue:, I think.

If you want the textbox to have pretty formatting, you'll need to split the minutes and seconds out as separate numbers I think and setup an appropriate looking string. Although there maybe some formatting options I'm not aware of.

Someone at the Lake Forest CA Cocoaheads meeting last night was asking about this kind of app too.

Hey, thanks for the post.

Actually though (for number two), my problem is more about the fact that I don't know where to put the code for the math. Right now all I've got is a "connection" (I don't know the "official" term) that causes the slider to send takeIntValueFrom to the label. I did that by just control-dragging, in interface builder, from the slider to the label and then selecting the method from the popup menu.

I do want as you said to change it so that it's formatted nicely with two variables placed neatly into a string, but to do that I suspect I need to overwrite the label's takeIntValueFrom method somehow. Unfortunately, I have no idea what to write or where to write it in order to do that. =/
 
Joined
Jun 25, 2005
Messages
3,231
Reaction score
112
Points
63
Location
On the road
Your Mac's Specs
2011 MBP, i7, 16GB RAM, MBP 2.16Ghz Core Duo, 2GB ram, Dual 867Mhz MDD, 1.75GB ram, ATI 9800 Pro vid
In your controller object you want to add an outlet of NSSlider type and an action for your slider to send to. You then control drag from the slider to your controller instance and connect to the action. Then you control drag from the controller to the slider and connect to your outlet. I think I have that the right way around.

Now in the action code, you do your math and update the text field. That will be called when the slider moves and you'll get the value from the slider via the takeIntValueFrom: message.

You should have an outlet for the text box too and connected via IB.

Do you have some books? How are you learning this stuff?
 
OP
S
Joined
Mar 4, 2010
Messages
51
Reaction score
0
Points
6
In your controller object you want to add an outlet of NSSlider type and an action for your slider to send to. You then control drag from the slider to your controller instance and connect to the action. Then you control drag from the controller to the slider and connect to your outlet. I think I have that the right way around.

Now in the action code, you do your math and update the text field. That will be called when the slider moves and you'll get the value from the slider via the takeIntValueFrom: message.

You should have an outlet for the text box too and connected via IB.

Do you have some books? How are you learning this stuff?

I did what you said, and it worked! Thank you! I didn't realize that I could connect a controller action to anything other than a button.

I've been learning it using some video podcasts, and then looking up things in the documentation when I hit a roadblock. I watched a few podcasts with the basics in them and then I decided to start writing my first project to see what I could do.
 
Joined
Jun 25, 2005
Messages
3,231
Reaction score
112
Points
63
Location
On the road
Your Mac's Specs
2011 MBP, i7, 16GB RAM, MBP 2.16Ghz Core Duo, 2GB ram, Dual 867Mhz MDD, 1.75GB ram, ATI 9800 Pro vid
The Stanford University iPhone course could be helpful too. It is available via iTunes. Sure, you'd have to watch out to not get confused with iPhone stuff and be open to finding the alternatives, such as NSView instead of UIView, but it is a well constructed course.

To add complication to your app, you could make the text box an interactive text field to allow the user to type in the time.
 
OP
S
Joined
Mar 4, 2010
Messages
51
Reaction score
0
Points
6
The Stanford University iPhone course could be helpful too. It is available via iTunes. Sure, you'd have to watch out to not get confused with iPhone stuff and be open to finding the alternatives, such as NSView instead of UIView, but it is a well constructed course.

To add complication to your app, you could make the text box an interactive text field to allow the user to type in the time.

Actually I'm learning xCode to eventually develop for the iPhone as an assistant programmer in my father's new company. I'm just writing a mac app to teach myself the basics of xCode. But at any rate, I'll have a look at the stanford course ^_^ Thanks for the recommendation.

But actually, I have a problem somewhat related to the first question now...

I was trying to change the timing system to use the NSDate, and now I'm having a bit of an issue with this method. I kept the NSTimer so I could update the level indicator every 1/8 second, but for some reason when the timer executes the countDown method, the app freezes. When viewing the console, it brings up something called "gdb" and one time it also said that the "program received signal: EXC_BAD_ACCESS". I have no idea what either of those things are. Here's the method that's causing the problem (you'll see below why I know this):

Code:
-(void)countDown
{	
	float barVal;

	// Set barVal to a float which is the % of time completed
	barVal = (float)[endTime timeIntervalSinceNow] / (float)startSeconds;
	
	[timeBar setFloatValue:ceil(barVal*240)];
	
	// When it's past endTime, call the timeOver method
	if ([endTime timeIntervalSinceNow]<=0) [self timeOver];
}

The above method is called repeatedly after using this code in the button action method:

Code:
// note to readers of this post: mainTimer variable created earlier
mainTimer = [NSTimer scheduledTimerWithTimeInterval:0.125 target:self selector:@selector(countDown) userInfo:nil repeats:YES];

It works if I comment out both the lines of the method that have a call to the timeIntervalSinceNow method; it doesn't work if I only comment out one or the other. I don't know what's wrong...any help appreciated.
 
Joined
Jun 25, 2005
Messages
3,231
Reaction score
112
Points
63
Location
On the road
Your Mac's Specs
2011 MBP, i7, 16GB RAM, MBP 2.16Ghz Core Duo, 2GB ram, Dual 867Mhz MDD, 1.75GB ram, ATI 9800 Pro vid
The first thing that I noticed is that your selector signature is wrong. It should have a colon in it. So this part
Code:
selector:@selector(countDown)
should look like
Code:
selector:@selector(countDown[COLOR="Red"][B]:[/B][/COLOR])

and the method should be declared with the colon like this
Code:
-(void)countDown:(NSTimer*)theTimer;

If endTime is an NSDate type, then I'm not sure why the crash is occurring, unless it hasn't been set up yet, or retained when you created it. I would put like these
Code:
NSLog(@"endTime: %@", endTime);
NSLog(@"endTime: %@", [endTime description]);
just before the first use of it in that method and see what gets printed in the console.

Also confirm via an NSLog that startSeconds is not zero.

By the way, have you considered what happens when you pass your NSLevelIndicatorCell a negative value? I didn't see any mention of negative numbers mentioned in the documentation.

As for gdb. That is the GNU Debugger. You use debuggers while the program is running. They allow you to set break points, inspect and reset variables, step through code and some other things. See this video for some debugging tips.

EXC_BAD_ACCESS means you have done something that caused your running program to try to access memory it isn't allowed to access. When you created endTime, was it retained? If the NSLog()s I mention above crash, that is a likely scenario.
 
OP
S
Joined
Mar 4, 2010
Messages
51
Reaction score
0
Points
6
The first thing that I noticed is that your selector signature is wrong. It should have a colon in it. So this part
<snip>
should look like
<snip>
and the method should be declared with the colon like this
<snip>

Uh, oops =p I'll fix that.

If endTime is an NSDate type, then I'm not sure why the crash is occurring, unless it hasn't been set up yet, or retained when you created it. I would put like these
Code:
NSLog(@"endTime: %@", endTime);
NSLog(@"endTime: %@", [endTime description]);
just before the first use of it in that method and see what gets printed in the console.

Yeah, I tried something like that (and I just tried your NSLog's as well), it crashes. =/ (without logging anything in the console) Also endTime is indeed an NSDate; here's my header code (before fixing the method you mentioned):

Code:
#import <Foundation/Foundation.h>

@interface timerController : NSObject {

	IBOutlet NSTextField *numOfMinutes;
	IBOutlet NSLevelIndicator *timeBar;
	IBOutlet NSSlider *timeSlider;
	IBOutlet NSButton *toggleButton;
	IBOutlet NSTextField *messageToShow;
	
	NSTimer *mainTimer;
	NSDate *endTime;
	
	float startSeconds;
	bool buttonState;
	
}

-(IBAction)toggleTimer:(id)sender;
-(IBAction)updateTextField:(id)sender;
-(void)countDown;
-(void)timeOver;

@end

Also confirm via an NSLog that startSeconds is not zero.
I just checked, it's the correct, non-zero value.

EXC_BAD_ACCESS means you have done something that caused your running program to try to access memory it isn't allowed to access. When you created endTime, was it retained? If the NSLog()s I mention above crash, that is a likely scenario.
I suspect you're right. I just don't know what's causing it.

Thanks for all your time and help with this, I seriously appreciate it.
 
Joined
Jun 25, 2005
Messages
3,231
Reaction score
112
Points
63
Location
On the road
Your Mac's Specs
2011 MBP, i7, 16GB RAM, MBP 2.16Ghz Core Duo, 2GB ram, Dual 867Mhz MDD, 1.75GB ram, ATI 9800 Pro vid
The fact that you get a crash at those NSLog()s suggests your endTime ivar isn't set, or you are not retaining it after setting it.

When is it crashing; upon opening the application, or when hitting the 'Start' button?

If it crashes at startup, then it sounds like you are initiating your timer when you haven't set things up yet. Specifically endTime. Your interface suggests that you are not initiating your timer because you haven't designated the obvious methods; awakeFromNib or init.

If it crashes when hitting the start button, have you used the slider yet to assign a value to endTime? What is the code that sets up endTime look like?

You need to look into Objective-C memory management. On the iPhone OS, you are responsible for it. Here is a link that covers some of it. There are several good tutorials at Cocoadevcentral.

The general rule for when you get a retained object back from classes is weather you have used the alloc, copy, or new class methods to create your object. If you have not, then you have an autoreleased object that you need to apply the retain method to if you want to keep it beyond the method you are in, even when that object is declared in your interface. Objects that are autoreleased get released at the end of the event loop. I'll leave it up to you to read about this. It is critical that you understand this and is to long to describe here.
 
OP
S
Joined
Mar 4, 2010
Messages
51
Reaction score
0
Points
6
I see. I knew I was missing something, I had no idea there was even a retain method at all. Haha. That would be the problem then, because I am using autoreleased objects.

Thanks for clearing this up, I've obviously got a lot to learn. Time to hit the books (or internet resources XD) I guess. Thanks again.
 

Shop Amazon


Shop for your Apple, Mac, iPhone and other computer products on Amazon.
We are a participant in the Amazon Services LLC Associates Program, an affiliate program designed to provide a means for us to earn fees by linking to Amazon and affiliated sites.
Top