PDA

View Full Version : What am I missing ? (IBActions and selectors)




Nekbeth
Apr 25, 2011, 02:27 PM
I get crashed if I use this code: (trying to create an outlet for a button with a selector to a method that invalidates the Time).


- (IBAction) cancelTime: (id) sender
{
[self performSelector:@selector(cancelIt:) withObject:nil];

}


- (void) cancelIt:(NSTimer*)timer

{

[timer invalidate];
timer = nil;


}

thanks



ulbador
Apr 25, 2011, 03:01 PM
What is "timer" set as and where does it come from?

I think from there you can see where your problem is.

Nekbeth
Apr 25, 2011, 03:28 PM
I declared timer as an instance method:

- (IBAction) cancelTime: (id) sender;
- (void) cancelIt:(NSTimer*) timer;

@end

mmm.. I think I see where this comes from. I had a similar method and it was declared in inside the (IBAction) method, like this:


- (IBAction) something: (id) sender;

[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(echoIt:) userInfo:myDict repeats:YES];

Then I would just implement echoIt.. That method works fine.

The question is, If I do the same, I'll be creating another NSTimer won't I ?, And I just want to access the same timer. What can I do?

Thanks

dejo
Apr 25, 2011, 03:39 PM
I declared timer as an instance method:

- (IBAction) cancelTime: (id) sender;
- (void) cancelIt:(NSTimer*) timer;

@end

No, you didn't. You declared cancelTime: and cancelIt: as instance methods, one of which happens to have a timer parameter.

As such, I'm not sure you have a proper grasp of the fundamental concepts of Objective-C programming so I would suggest you step away from the real coding and go (re)learn those before you come back to this issue.

Nekbeth
Apr 25, 2011, 04:00 PM
Thanks for your advice dejo, but I'm not stepping away because of lack of fundamentals. Interaction with other developers is an additional learning source (the main is all kind of documentation), of course I need to learn more about fundamentals of objective C just like you did when you had 3 months programming, but that ain't stopping me from asking help in forums. Some people help you, some don't, you just have to deal with that.

btw, thanks for pointing my error, your right.. those are declaration for cancelTime: and cancelIt: , I got confuse with the parameter :D

dejo
Apr 25, 2011, 04:20 PM
Thanks for your advice dejo, but I'm not stepping away because of lack of fundamentals. Interaction with other developers is an additional learning source (the main is all kind of documentation), of course I need to learn more about fundamentals of objective C just like you did when you had 3 months programming, but that ain't stopping me from asking help in forums. Some people help you, some don't, you just have to deal with that.
The reason I suggested what I suggested was that, without a good grasp of the fundamentals, you are not exactly speaking the same language as those you seek help from. This can cause continued confusion and frustration by all involved. Anyways, good luck with your issue.

Nekbeth
Apr 25, 2011, 04:49 PM
No problem dejo, I understand.. It can be frustrating for others as well as myself and that's why some people tell you to go read all Apple's documentation for a simple question and some others help you no matter what. Speaking a language fluidly could take years, I can hardly speak French myself but that is not stoping me from going to France & ask for coffee in their language. (even if they get upset cause I talk awful, which some do, but some others like it :P).

About my issue, I think I solve it. I was able to show up an alarm with using that method after I declare it appropriately.

I now have some thing like this :

- (IBAction) cancelTime: (id) sender
{

[NSTimer scheduledTimerWithTimeInterval:0
target:self
selector:@selector(cancelIt:)
userInfo:nil
repeats:NO];


}


- (void) cancelIt:(NSTimer*)timer

{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"An Alert!"
delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];


}

I'll now try to add the invalidate method to the timer, see what happens

dejo
Apr 25, 2011, 05:16 PM
What makes you think that cancelIt: is being passed an NSTimer object?

Nekbeth
Apr 25, 2011, 05:37 PM
Because I have a button that receives the action "cancelTime" in IB. I wonder if I need to add something to userInfo parameter in the cancelTime method. Please correct me if I'm missing something.

EDIT:

UPdate !!,

Just to confirm that I was not able to access the Timer, only it's window. My guess is that I need to add some userInfo to access it.

ulbador
Apr 26, 2011, 09:59 AM
The point dejo was trying to make, is that you are missing a VERY basic Objective C (well, any language really) fundamental.

This:


- (void) cancelIt:(NSTimer*)timer


does NOT create an object.

It's simply a map to say "When I call this method, I will pass in an existing timer object". It is still your responsibility to allocate/initialize a timer and then pass that into your method. Simply using the selector as you are doing wouldn't accomplish this.

At some point you would have to do something like:


[self cancelIt:MyExistingAndValidTimerObject];

Nekbeth
Apr 26, 2011, 10:29 AM
I'm aware of that ulbador, and my point is that like any other language.. you get better with time & practice. Nobody FORCES you or dejo to read my threads, or answer them. If you see lack of objective-C fundamentals, just go to another thread (for Pros), is that simple. Some people like to help, others laugh, others ignore you or get frustrated because they can't read ... who cares man, if you don't like the thread just go to another one but never try to discourage a person who's starting to learn, that I'm against.


(about the code) Thanks for pointing that out, I needed a variable, after that I created a timer appropriately and used the variable as a reference to trigger my cancel methods (invalidate).

wlh99
Apr 26, 2011, 05:44 PM
I'm aware of that ulbador, and my point is that like any other language.. you get better with time & practice. Nobody FORCES you or dejo to read my threads, or answer them. If you see lack of objective-C fundamentals, just go to another thread (for Pros), is that simple. Some people like to help, others laugh, others ignore you or get frustrated because they can't read ... who cares man, if you don't like the thread just go to another one but never try to discourage a person who's starting to learn, that I'm against.


(about the code) Thanks for pointing that out, I needed a variable, after that I created a timer appropriately and used the variable as a reference to trigger my cancel methods (invalidate).

Have you read the documentation for NSTimer?

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds invocation:(NSInvocation *)invocation repeats:(BOOL)repeats


The above line has your answer.

Nekbeth
Apr 26, 2011, 06:06 PM
I got it wlh99, thanks. I have two timer working fine (finally :) , I was told that you can't reuse the same timer, hence the 2nd timer. There is one Start button and one Cancel button

Now I'm trying to find a logic to turn the 1st timer ON while the 2nd is OFF, then if you press Cancel you invalidate that 1st timer.

I have both timers starting at the same time. So, i'm sure I could work it out using an if /condition statement.. something like :

// *myTimer is the 1st timer
// *newTimer is the 2nd timer


if (myTimer != newTimer) {

// Code to start new Timer
}

Any idea would be great, thanks

wlh99
Apr 26, 2011, 06:32 PM
// *myTimer is the 1st timer
// *newTimer is the 2nd timer


if (myTimer != newTimer) {

// Code to start new Timer
}

Any idea would be great, thanks

Do you understand pointers, and that myTImer and newTimer are both pointers to NSTimer objects? If not, then step back and learn some Objective-C basics.

What do you mean by "ON" and "OFF"?

If you read the NSTimer documentation, it will tell you how to find out information about it, for example if it is Valid, or what the next fire date/time is.

Your if statement will confirm that the two pointers don't point to the same single timer object. I don't know what you want to do from reading your post, but I'm sure it isn't that.

So first thing first, what do you want to do?

dejo
Apr 26, 2011, 06:51 PM
If not, then step back and learn some Objective-C basics.

Careful. The OP doesn't like to hear that. :)

Nekbeth
Apr 26, 2011, 07:04 PM
Easy fellows.. :) .. those are not pointers ... they have "//" to indicate it's a comment.(you should both know this) I usually use ** as comments. It's an obvious miss understanding. They are just there to indicate you that Timer1 is the 1st Timer, ITS NOT PART OF THE CODE.

I lack fundamentals, but not that much.. so hold your horses. dejo, please stay out of it, go to check some Pro Forums and cut some slack, what I don't like to hear is people trying to discourage new developers to stay off real code cause they miss a fundamental.

wlh99, I'll step back when ever I want to, this is a public Forum and people are here to discuss and learn new stuff.

Any way.. if you guys can't help me, just go to another thread.

wlh99
Apr 26, 2011, 07:41 PM
...

wlh99, I'll step back when ever I want to, this is a public Forum and people are here to discuss and learn new stuff.

Any way.. if you guys can't help me, just go to another thread.

I'm more than happy to help, which is why I asked what you meant by "ON" and "OFF" and what exactly you want to do. Because I don't know. Timers are not "ON" or "OFF" so I need to know what you mean.

I was referring to the "if" statement, not the comment. How and where do you declare myTimer and newTimer? Where are they assigned a value? Post that code. My assumption was (possibly incorrect) that they were assigned as the return value from when you created the timers.

In which case, they are pointers. If you declared them as a primitive type and assigned them a value not related to the timer objects, then they are not pointers. If that is the case, I am even more confused as to what you want the program to do.

Post your code, and let us know what you are trying to accomplish.

dejo
Apr 26, 2011, 07:50 PM
dejo, please stay out of it, go to check some Pro Forums and cut some slack, what I don't like to hear is people trying to discourage new developers to stay off real code cause they miss a fundamental.
Nekbeth, I'm not sure if you follow other threads in this forum but if you do, you'll find that I have been quite helpful to a number other beginners out there. I am not trying to discourage new developers; I am just trying to help you help yourself so that you have a better chance of getting the answers you seek when you can ask questions using the same terminology as everyone else.

But if you don't want my help, I'm happy to oblige. Good luck, though.

Nekbeth
Apr 26, 2011, 08:08 PM
Sure, good to have that clear.

Then yes, they are indeed pointers to timers. The timers are created inside their methods, I use those pointers to reference them and use invalidate.

Here is part of the code:

.h (declaration of timers)
@interface ATimerViewController : UIViewController {

IBOutlet UIDatePicker *timePicker;
NSTimer *myTimer;
NSTimer *newTimer;


// 1st Timer
- (IBAction) echoTime: (id) sender;
- (void) echoIt: (NSTimer *) timer;


// 2nd TIMER
- (IBAction) newActionTimer: (id)sender;
- (void) echoNewTimer: (NSTimer *) timer2;


.m (method for 2nd Timer , the other is similar)

---------------- 2nd Timer -----------------


- (IBAction) newActionTimer: (id)sender
{
[newTimer invalidate];
[newTimer release];

NSDate * time = timePicker.date;
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:@"HH:MM:SS"];
NSLog(@"date:%@", [dateFormatter stringFromDate:time]);
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [gregorian components:(NSHourCalendarUnit | NSMinuteCalendarUnit) fromDate:time];

NSInteger hour = [comps hour];
NSInteger minute = [comps minute];
NSLog(@"Hour:%i", hour);
NSLog(@"minute:%i", minute);
NSInteger secs =hour * 60 * 60 + minute * 60;

NSNumber *elapsedSeconds = [NSNumber numberWithInt:secs];
NSDictionary *myDict2 = [NSDictionary dictionaryWithObject:elapsedSeconds forKey:@"TotalSeconds"];

newTimer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(echoNewTimer:)
userInfo:myDict2
repeats:YES];

[newTimer retain];

}



- (void) echoNewTimer: (NSTimer *)timer2

{

NSNumber *num = (NSNumber *) [[timer2 userInfo] valueForKey:@"TotalSeconds"]; //elapsed
seconds++;

NSInteger secs2 = [num integerValue] - seconds; //remaining
NSLog(@"elapsed: %i, remaining: %i", seconds, secs2);

if (secs2 <= 0)
{
[timer2 invalidate];
timer2 = nil;

}

label4.text = [NSString stringWithFormat:@"NEW TIMER: %i", secs2];
}


After that I implement a Cancel method pointing to sender (button)

So, my goal is to use 1 start button and 1 cancel button.. and just do their actions. I have set up a the start button to start both timers, obviously both start their countdown at the same time which is not good.

I want to tell one timer to start and if I press cancel, invalidate it. Then If I press start again, call the second timer. (I do this because I read that you can't reuse a timer after you invalidate it).

Some people have suggested to use Booleans like true or false, or conditions. What do you think?

balamw
Apr 26, 2011, 08:21 PM
Post your code, and let us know what you are trying to accomplish.

Nekbeth, let me suggest that you take some time to read over http://whathaveyoutried.com and http://mikeash.com/getting_answers.html.

dejo, ulbador and wlh99 are genuinely trying to help you, but you have not defined the problem or given them (or anyone else) enough information to work with in order to be able to help you.

Part of the problem, which dejo already alluded to, is that without a common understanding of fundamental assumptions you both end up frustrated. You might well be able to ask for a coffee in French, but if you are in a dentist's office in Austria that might not lead to satisfaction all around. Your assumptions aren't in sync.

B

Nekbeth
Apr 26, 2011, 08:23 PM
Of course I like help Dejo and I know you have help a lot people, you have even helped me before this thread and I appreciate it a lot. I said that because so many seasoned developers just throw that bomb at newbies so often when they try to find answers in forums (not just this one), it happens not only in Programming but in many other professional environments, people just shoot to kill when some new guy makes a basic mistake, but luckily not all, some people do like to help (or enjoy) and have the patience to explain even the dumbest detail. But hey, it's cool.. We're all here to share and learn after all. I'll be glad to see you contribute to my threads, but you know.. that is up to you.

balamw
Apr 26, 2011, 08:33 PM
Of course I like help Dejo and I know you have help a lot people, you have even helped me before this thread and I appreciate it a lot. I said that because so many seasoned developers just throw that bomb at newbies so often when they try to find answers in forums (not just this one), it happens not only in Programming but in many other professional environments, people just shoot to kill when some new guy makes a basic mistake, but luckily not all, some people do like to help (or enjoy) and have the patience to explain even the dumbest detail.

Please take the time to read the two guides I linked in my response a few posts back.

This: Easy fellows.. :) .. those are not pointers ...

Then yes, they are indeed pointers to timers.
is exactly what they seek to avoid.

Help us help you.

You take it as a "bomb" when in fact it is a request to get on the same page.

B


I want to tell one timer to start and if I press cancel, invalidate it. Then If I press start again, call the second timer. (I do this because I read that you can't reuse a timer after you invalidate it).

So this will effectively be a stopwatch that can only by started and stopped twice?

Is that the intent?

EDIT: Have a look at this tutorial: http://www.apptite.be/blog/ios/sample-ios-application-stopwatch/ Do you understand why it doesn't need to define two timers?

B

KnightWRX
Apr 26, 2011, 08:43 PM
I want to tell one timer to start and if I press cancel, invalidate it. Then If I press start again, call the second timer. (I do this because I read that you can't reuse a timer after you invalidate it).

You don't need to do this. You can use the same NSTimer * pointer multiple times, you will just need to assign a new NSTimer object to it after you invalidated your first NSTimer object (or 2nd, or 3rd, etc..).

Basically, you only need 1 NSTimer object pointer, setup as an instance variable and your various IBActions :

(now, sorry for any syntax/compile error, I'm not opening Xcode here, just typing it out)

@interface ATimerViewController: UIViewController {
NSTimer * atimer;
}

-(IBAction)setAndStartTimer:(id) sender;
-(IBAction)cancelTimer:(id) sender;



This is basically all you would need. Pressing the start button would call the first method, clicking the cancel button would call the second.

Did you read the NSTimer class reference (http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSTimer_Class/Reference/NSTimer.html) ? It explains what [atimer invalidate] does (also its pitfalls). It also explains how to create timer objects.

ulbador
Apr 26, 2011, 08:43 PM
The OP is shockingly confused. When it says that you can't reuse an invalidated NSTimer, that just means you have to create a new instance. You can reuse that pointer as much as you want once you invalidate and release it.

Nekbeth
Apr 26, 2011, 08:44 PM
is that last code enough info balamw?

Satisfying?, well that's pretty much impossible if you ask me. People have their own standards, some are satisfied with you understanding the basic language, some others just want to read perfect code or hear perfect English and can't tolerate a miss step.

I say show what you got (even it's a poor language) and follow your needs because you can never satisfy people expectations. Soon or later, you'll talk as good or better than them. It's only matter of will, time and patience.

I know they are all trying to help, but there are ways to tell people what they lack, and those ways are what make all the difference.

You can point out an error and give solution (sorry, "find solutions") or you can tell that person to quit what he's doing because he has no idea. It's a lot easier to say, go read Apples documentation than to point out an error and explain it yourself.

KnightWRX
Apr 26, 2011, 08:49 PM
You can point out an error and give solution

The goal of the forum is not to give out solutions, sorry. If that is what you are looking for, you're looking for it in the wrong places. We're here to help you figure out how to find the solution yourself (either by pointing out appropriate documentation or by giving hints).

or you can tell that person to quit what he's doing because he has no idea. It's a lot easier to say, go read Apples documentation than to point out an error and explain it yourself.

No one told you to quit and pointing out the documentation often times is better than someone trying to explain it. The documentation will be correct, and why type out an explanation to something Apple already documentation (ie, explained) in the proper terms ?

Now if there's something in the documentation you need help clarifying, please feel free to ask questions about the documentation.

Nekbeth
Apr 26, 2011, 08:52 PM
thanks ulbador, the OP understands now :D

If OP wasn't confused he wouldn't have created a thread.

balamw
Apr 26, 2011, 08:53 PM
is that last code enough info balamw?


Still too much left out. "After that I implement a Cancel method pointing to sender (button)" should tell you you are leaving potentially important stuff out.

You can point out an error and give solution or you can tell that person to quit what he's doing because he has no idea. It's a lot easier to say, go read Apples documentation than to point out an error and explain it yourself.

No one is telling you to quit. They're telling you to go back and make sure you understand objects. (Clearly you don't). This is something you will have to understand for yourself.

As it stands you are confusing yourself.

I don't think I've been involved in any of your threads. What resources are you using to learn Objective-C?

B

wlh99
Apr 26, 2011, 08:59 PM
After that I implement a Cancel method pointing to sender (button)

So, my goal is to use 1 start button and 1 cancel button.. and just do their actions. I have set up a the start button to start both timers, obviously both start their countdown at the same time which is not good.

I want to tell one timer to start and if I press cancel, invalidate it. Then If I press start again, call the second timer. (I do this because I read that you can't reuse a timer after you invalidate it).

Some people have suggested to use Booleans like true or false, or conditions. What do you think?

What if after pressing the start button, you create a timer and start it. Then pressing the cancel button invalidates and releases it. Then pressing the start button would create another timer, using the same pointer.

Totally untested and probably broken code below, but should demonstrate the idea:


-(IBAction)startButton:(id) sender {
// myTimer is declared in header file ...

if (myTimer!=nil) { // if the pointer already points to a timer, you don't want to create a second one without stoping and destroying the first

[myTimer invalidate];
[myTimer release];

}

// Now that we know myTimer doesn't point to a timer already..

myTimer = [NSTimer scheduledTimerWithTimeInterval:aTimeInterval target:self selector:@selector(echoIt:) userInfo:myDict repeats:YES];
[myTimer retain];
}

-(IBAction)cancelIt:(id) sender {
[myTimer invalidate];
[myTimer release]; // This timer is now gone, and you won't reuse it.
}

Nekbeth
Apr 26, 2011, 09:02 PM
Thanks for the explanation Knight, I got confuse with pointers and objects.

I'll give a try now. See how it goes.

Man, we could go forever here. hahaa.

wlh99 , you just described exactly what I want to do.

balamw
Apr 26, 2011, 09:12 PM
wlh99 , you just described exactly what I want to do.

And what was in the tutorial I linked and the code that KnightWRX posted ...

B

Nekbeth
Apr 26, 2011, 09:24 PM
Update **

It now works !! that logic will help me a lot with future projects.

thanks wlh99 and to everyone who contribute.

PhoneyDeveloper
Apr 26, 2011, 10:22 PM
Nekbeth, you didn't thank Philip Endecott, who posted the solution to your problem on the Apple forum about three hours before wlh99 posted essentially the same solution here.

Nekbeth
Apr 26, 2011, 10:29 PM
What if after pressing the start button, you create a timer and start it. Then pressing the cancel button invalidates and releases it. Then pressing the start button would create another timer, using the same pointer.

Totally untested and probably broken code below, but should demonstrate the idea:


-(IBAction)startButton:(id) sender {
// myTimer is declared in header file ...

if (myTimer!=nil) { // if the pointer already points to a timer, you don't want to create a second one without stoping and destroying the first

[myTimer invalidate];
[myTimer release];

}

// Now that we know myTimer doesn't point to a timer already..

myTimer = [NSTimer scheduledTimerWithTimeInterval:aTimeInterval target:self selector:@selector(echoIt:) userInfo:myDict repeats:YES];
[myTimer retain];
}

-(IBAction)cancelIt:(id) sender {
[myTimer invalidate];
[myTimer release]; // This timer is now gone, and you won't reuse it.
}



Update *** "I though it worked but the timer kept going on the background.

crashed :confused:

wlh99, do you get an exception in the invalid method " [myTimer Invalidate]" ?

PhoneyDeveloper
Apr 26, 2011, 10:39 PM
You should have used Philip Endecott's code.

Nekbeth
Apr 26, 2011, 10:41 PM
Nekbeth, you didn't thank Philip Endecott, who posted the solution to your problem on the Apple forum about three hours before wlh99 posted essentially the same solution here.

I did PhoneyDeveloper, it just that his explanation only stops the timer, if I press StartTimer again, the seconds continue where they left. e.g.

startTimer 59,58, cancel.. startTimer 57,56 and so on.



mmm.. I see where there might be problem (my fault, not Phillips).. I'll come back..

wlh99
Apr 27, 2011, 09:34 AM
Update *** "I though it worked but the timer kept going on the background.

crashed :confused:

wlh99, do you get an exception in the invalid method " [myTimer Invalidate]" ?

I didn't test the code at all, so no. But it doesn't surprise me. An exception is thrown when you try to message an object that no longer exists.

I test to see if myTimer is nil as a check to see if the my timer object exists. But elsewhere in the progam I release myTimer and never set myTimer to nil. So, the pointer still points to a memory location, but no object is there so the [myTimer invalidate] fails with an exception. It's a very beginner mistake on my part.

add
mytimer = nil;
to the cancelIt: method.

I strongly recommend reading this document:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html

The important thing (assuming you are trying to learn to program) is that you don't just accept that it works, and that instead you know why what you were doing was wrong, and why the answer works.

Look at your first post. Can you say why it crashes? ulbadr's response was pretty direct in his answer, and you didn't understand it. Do you understand it now? Can you say for sure what the code you first posted does, and why it crashes?

Nekbeth
Apr 27, 2011, 10:25 AM
I see where you going wlh99, and don't worry.. my full intention is to learn, not to get code from all of you. Many people in this thread underestimate my knowledge of objective C (and I understand why, I got lost with the pointers). I have 2 1/2 months since I started development and had 0 idea of the language or programming (I was a Pastry Chef actually :D, which is the name of my first app).

Believe me when I tell you that I know what's going on with my code. I'm aware that If you release an object that it doesn't exist you'll get an exception every time.

Making it work is a lot less important than knowing how to do it, for future work.

Back to the Code, let me go give it try.. b-back


UPDATE**

Ok, it doesn't crash now but timer still won't restart. I'm going to create another timer object (not pointer, I'll use the same pointer). I get this idea that I can't reuse or reset the same timer over again (invalidating and releasing it only pauses the timer). Wish me luck :)

dejo
Apr 27, 2011, 11:17 AM
I still think it would help us if you described, at a high-level, what it is you are trying to accomplish.

From what I can gather you want a countdown timer: a label that shows the seconds remaining, along with two buttons, one to start the countdown and one to cancel it. After the Start button is tapped, the label will start showing the seconds counting down. If the Cancel button is tapped, the countdown stops and is reset, so that if you tap Start again it begins back at 60 seconds. Is that correct?

If so, I think you need to be aware that a countdown-timer and NSTimer are very different things.

Nekbeth
Apr 27, 2011, 11:34 AM
Yes, that's exactly what I want to accomplish dejo.

Please, enlighten me .. what is the difference between the countdown-timer and NSTimer?. I though you must use NSTimer to get a countdown or count up timer. Feel free to explain or not, you can also give me link or reference, I'll read it. I want to learn all those stuff.

wlh99
Apr 27, 2011, 11:34 AM
I see where you going wlh99, and don't worry.. my full intention is to learn, not to get code from all of you. Many people in this thread underestimate my knowledge of objective C (and I understand why, I got lost with the pointers). I have 2 1/2 months since I started development and had 0 idea of the language or programming (I was a Pastry Chef actually :D, which is the name of my first app).

Believe me when I tell you that I know what's going on with my code. I'm aware that If you release an object that it doesn't exist you'll get an exception every time.

Making it work is a lot less important than knowing how to do it, for future work.

Back to the Code, let me go give it try.. b-back


UPDATE**

Ok, it doesn't crash now but timer still won't restart. I'm going to create another timer object (not pointer, I'll use the same pointer). I get this idea that I can't reuse or reset the same timer over again (invalidating and releasing it only pauses the timer). Wish me luck :)

Good luck.

Post your echoIt: method. If you are displaying elapsed seconds or something, the code to calculate and display that might be your issue.

Nekbeth
Apr 27, 2011, 11:43 AM
Thanks, here is the echoIt method :

- (void) echoIt:(NSTimer *)timer // SECONDS METHOD

{

NSNumber *num = (NSNumber *) [[timer userInfo] valueForKey:@"TotalSeconds"]; //elapsed
seconds++;

NSInteger secs = [num integerValue] - seconds; //remaining
NSLog(@"elapsed: %i, remaining: %i", seconds, secs);

if (secs <= 0)
{
[timer invalidate];
timer = nil;

}

label3.text = [NSString stringWithFormat:@"Seconds remaining: %i", secs];

}

dejo
Apr 27, 2011, 01:01 PM
Yes, that's exactly what I want to accomplish dejo.
Good. Now we're getting somewhere.

Please, enlighten me .. what is the difference between the countdown-timer and NSTimer?
Let me ask you this: what do you think the difference is?

I though you must use NSTimer to get a countdown or count up timer.
Using an NSTimer is certainly a common approach to the problem of modeling a countdown timer, but it's certainly not the only one. Because the timer is tied to the main run loop, it is not guaranteed to actually fire every second (in your case). In that case, perhaps the use of NSDate to keep track of seconds elapsed would be a better approach.

Nekbeth
Apr 27, 2011, 01:13 PM
Let me ask you this: what do you think the difference is?


I hope it's not a rhetorical question, but I really don't know, that is why I asked.

Check out this timer tutorial. I'm trying to follow it by adding a Datepicker to it. Let me know what you think of it.

http://www.youtube.com/watch?v=5jmTQi98vec&feature=related

wlh99
Apr 27, 2011, 01:46 PM
Thanks, here is the echoIt method :

- (void) echoIt:(NSTimer *)timer // SECONDS METHOD

{

NSNumber *num = (NSNumber *) [[timer userInfo] valueForKey:@"TotalSeconds"]; //elapsed
seconds++;

NSInteger secs = [num integerValue] - seconds; //remaining
NSLog(@"elapsed: %i, remaining: %i", seconds, secs);

if (secs <= 0)
{
[timer invalidate];
timer = nil;

}

label3.text = [NSString stringWithFormat:@"Seconds remaining: %i", secs];

}

Where is userInfo declared, and as what? Are you passing the same userInfo object to each timer you create, or are you creating a new one? I'm actually not following what you are using that for. I might suggest just passing nil as the user info and ignoring it in this method.
*** Edit: I now see why. For simplicity for now, I would ignore it.

You increment seconds in this method. Where is seconds initalized, and is it re-initalized for the start of the second timer? Or do you just keep incrementing it starting from where it left off? Either could be correct, depending on your goal. A typical handheld stopwatch has a start, stop, and reset, buttons.

As dejo pointed out, the method you are using is a very inaccurate timer. Say you set the interval to 1 sec. (which I assume you did). The timer will fire approxamatly every one second, but not exactly. So by counting seconds as you do the error will add up possibly quickly.

I would second dejo's approach. I would still use an NSTimer, but instead of counting seconds, I would calculate them with NSDate.

The documentation to NSDate is here:
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSDate_Class/Reference/Reference.html
Conviently, it has a method to calculate the time difference between two NSDates.

I hope it's not a rhetorical question, but I really don't know, that is why I asked.

Check out this timer tutorial. I'm trying to follow it by adding a Datepicker to it. Let me know what you think of it.

http://www.youtube.com/watch?v=5jmTQi98vec&feature=related

What do you know about NSTimer? In one sentence, can you tell us precisely what it does? Is that what a your idea of a countdown-timer does?

Do you know what "send a message to a target" means?

I will take a look at the video when I get home tonight.

Nekbeth
Apr 27, 2011, 02:05 PM
Target is the object that the message is going to execute isn't it. For example, if it's self, that means that those parameters are for the timer object you just created. Please correct me if I'm wrong, I'm not trying to challenge your knowledge, just to learn as I go.

If you see my code before, I'm using NSDate for my timePicker. One favor, I'm not answering more quiz questions, I get your point.. I still need to learn more fundamentals.. I get it, just please contribute with the thread to find solutions or not.. (there are many Professional Forums).

wlh99
Apr 27, 2011, 02:44 PM
Target is the object that the message is going to execute isn't it. For example, if it's self, that means that those parameters are for the timer object you just created. Please correct me if I'm wrong, I'm not trying to challenge your knowledge, just to learn as I go.

If you see my code before, I'm using NSDate for my timePicker. One favor, I'm not answering more quiz questions, I get your point.. I still need to learn more fundamentals.. I get it, just please contribute with the thread to find solutions or not.. (there are many Professional Forums).

If this were a "Professional Forum" I would just give you an answer. I want to know what you do and do not know, so I can help you learn it. So please don't take the questions as condescending, they will help us help you.

Think of objects as people, so to speak. Not only is the NSTimer an object, but so is your viewcontroller. So are the buttons. These objects know how to do things. These things they know how to do are methods. A message is an instruction for an object to do something.

cancelIt: is a method in your viewcontroller object, as are all the methods we have discussed. Then self would refer to the viewcontroller, not the timer. Self would refer to the timer if you had access to apples code that implemets the timer and you were modifiying that.

So a target is the object you are sending a message to. The message is the name of the method you want the object to execute.

[aTimer invalidate]; // tells the timer pointed to by aTimer to execute the invalidate method

When you press a button, a message is sent. The target and method are chosen when you make the connection in Interface Builder. In your case, the target is your viewcontroller, and the method is one of the start or cancel methods.

I asked the question becasue it is fundamental to what an NSTimer is/does.

An NSTimer sends a message to an object at regular intervals.

In your case, the NSTimer is telling your viewcontroller to execute the echoIt: every second. The important part is that your viewcontroller is an object, echoIt: is something your viewcontroller is doing (not the timer). You only have one viewcontroller, so anything it stores (for example seconds) will persit for any NSTimer you create.

Now look at the NSTimer documentation:

(NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats


This returns a pointer to an NSTimer object (NSTimer *).
NSTimeInterval is how often a message will be sent to target.
In your case you use self to refer to your viewcontroller.
selector is the message you will be sending to your viewcontroller.

As a comparision, you could connect a button to echoIt: the same way you connect a button to startButton. If you pressed that button 1 time each second, that is the same thing the timer does.

Nekbeth
Apr 27, 2011, 03:06 PM
Thanks, that's good information. I actually got caught up trying to finish this function of my App but I plan immediately to deep into books and videos that I already have waiting for me. Believe or not, I'm looking forward to it. I know that as soon as give some time to read over fundamentals like the ones you mention.. it will be easier for and easier for all of you to understand my threads.

So, self refers to my controller.. interesting.

balamw
Apr 27, 2011, 05:32 PM
One favor, I'm not answering more quiz questions, I get your point.. I still need to learn more fundamentals.. I get it, just please contribute with the thread to find solutions or not.. (there are many Professional Forums).

You clearly have not read the two articles I linked back in post #20 http://forums.macrumors.com/showpost.php?p=12467980&postcount=20.

You don't "get it".

The "quiz questions" are necessary because we don't know what it is you know or think you know. We can't read your mind. This is how information is exchanged and we can come to the appropriate level or explanation to be able to help you. It can also help you find the answer yourself by talking through it.

Helping you help yourself is the best way we know how to contribute to the thread.

We've all been there, even the hard-core pros. Sometimes you just can't see the answer that is right in front of your eyes until you try explaining it so someone else.

Please answer this question which I posed earlier in the thread. What books, sites, videos, etc... have you been using to get you to this point and what additional resources are you looking to delve into next.

Given the things it is clear you don't understand, picking the right resources to use to learn the fundamentals you are missing is quite important.

EDIT: Finally, just a comment, PhoneyDeveloper pointed out that you had a parallel thread on the Apple Discussion forums. JMHO, but that's poor netiquette and is a waste of both your time and ours. At least link the two conversations, so folks don't end up repeating what someone else said on the other forum. Even just to say "someone over at the Apple Discussion Fourms (link) suggested ..."

B

Nekbeth
Apr 27, 2011, 06:18 PM
EDIT: Finally, just a comment, PhoneyDeveloper pointed out that you had a parallel thread on the Apple Discussion forums. JMHO, but that's poor netiquette and is a waste of both your time and ours. At least link the two conversations, so folks don't end up repeating what someone else said on the other forum. Even just to say "someone over at the Apple Discussion Fourms (link) suggested ..."

B

Let me tell you something balamw, and I want you to remember it because it's obvious that you don't get my point either, even if I have said it over 10 times in this thread.

If you don't want to participate on my threads, stay out of it. Nobody is forcing you to read or post comment, alright ? If I want to open 10 threads on the subject in 10 different forums, well.. **** it.. that is how I like it. I'm not wasting anybodies time if they don't want to. Just ignore it and go to another one. I hope this is clear from now on.

About your links.. don't post them again.. I open one and read two paragraphs, I know where thats going. I could post 3 pages explaining you why and how Pro Developers should help Newbies but I not going to do that.

Next thing, quiz question: Just go ahead and ask, you can do as you like here; you'll sometimes get my answers just as sometimes I gets yours.

Again, thanks to all for commenting and helping.

My sources.. well, my main sources is the Apple documentation (all of it), then theres books and all the same stuff than most developers learn from. And.. no I haven't read all of the books, nor watch every video but I will.

I may not understand it all now balamw but give me a year or two and will see who needs some catching up to do.

well, back to work :)

KnightWRX
Apr 27, 2011, 06:22 PM
For someone seeking our help, you sure are quick to dismiss it. Again, everyone in this thread has been trying to help you. A little cooperation on your part would be appreciated.

Help us help you. If we have questions, it's because we don't quite understand what you are seeking help on.

Nekbeth
Apr 27, 2011, 06:33 PM
The "quiz questions" are necessary because we don't know what it is you know or think you know. We can't read your mind. This is how information is exchanged and we can come to the appropriate level or explanation to be able to help you. It can also help you find the answer yourself by talking through it.



talking through it ?? thats funny, as soon as someone mentions "what's a pointer"..everyone shoots to kill here, and they tell you to step out or go deep yourself in books. The last thing you'll get is a simple answer, which 1 out 20 developers give you without asking you "Have you even read the objective-C manual?? cause if not you should leave the Real Coding and go study now"

For someone seeking our help, you sure are quick to dismiss it. Again, everyone in this thread has been trying to help you. A little cooperation on your part would be appreciated.

Help us help you. If we have questions, it's because we don't quite understand what you are seeking help on.


Knight, just go to page 2 and look at the problem. It's very clear what I'm looking for and many developers have try to solve it. dejo describes it step by step. If you don't understand ask me, because many others understand it.

(I think 2/3 pages in this thread are not related to the code itself, instead everybody is giving his point of view about why or why not Pro developers should help new ones.)

KnightWRX
Apr 27, 2011, 06:53 PM
everybody is giving his point of view about why or why not Pro developers should help new ones.)

No one has given a point of view about that. You quite misunderstand what everyone is saying.

As for your code, you still have not really given us a clear indication of at what stage you are now and what isn't working. Now we know you want to do a sort of count down timer. I'm guessing you're trying to make a cooking timer kind of app since you said you were a pastry chef and that was what your first app was based on. Is this correct ? (<-- not a quiz question).

Now, what is not working ? Is the timer getting created ? Is it calling the method identified by the target and selector attributes when the interval you specified ends ? Is it repeating or not repeating (depending on how you set the repeat parameter on it) ?

When a timer repeats, it will simply call back the selector in the target specified.

Does your button that "cancels" it call your cancel method ? What have you done to check this ?

With the little code you posted, and since you haven't provided screenshots of your associations in Interface Builder, these are all pending questions we have that are preventing us from helping you thoroughly. This is not a quiz, these are things we need to know to help you.

So, self refers to my controller.. interesting.

No, self refers to the instance of the object that is executing the currently running code. It is highly context dependant.

Inside a method of your view controller, yes, self refers to your view controller. Inside a method in your view object, self refers to the view object. Inside the NSTimer object, self refers to the NSTimer.

balamw
Apr 27, 2011, 07:04 PM
My sources.. well, my main sources is the Apple documentation (all of it), then theres books and all the same stuff than most developers learn from. And.. no I haven't read all of the books, nor watch every video but I will.

Again with the lack of specificity. :rolleyes:

Being specific is a huge part of learning how to program, because computers only do what you tell them to do. (As you should have learned just by living through this thread).

It's not essential to read every page of every book, but certain books are good at explaining particular concepts. Others, less so.

Telling us specifically which resources got you in this mess, can help us point you at the relevant portions of the resources you already have at your disposal. It also can help us the next newbie who doesn't know a method from an object instance, by pointing them to different resources to avoid your mistakes.

For example, if we know you have access to Kochan's book we could be more specific and say: "Go back and re-read Chapter 3 on "Classes, Objects and Methods"" instead of a more generic "step back and learn the fundamentals".


No, self refers to the instance of the object that is executing the currently running code.

Which Nekbeth might actually know if they took the time to learn something about objects, for example from said Chapter 3 in Kochan. For me, it remains the best description of objects I have read.

B

PhoneyDeveloper
Apr 27, 2011, 07:14 PM
If I want to open 10 threads on the subject in 10 different forums, well.. **** it.. that is how I like it.

If you want to take a dump in the pool because "that's the way you like it" that's fine. Don't expect anyone else to like it.

(I think 2/3 pages in this thread are not related to the code itself, instead everybody is giving his point of view about why or why not Pro developers should help new ones.)

Obviously you attract that, for some reason.

balamw
Apr 27, 2011, 07:20 PM
talking through it ?? thats funny, as soon as someone mentions "what's a pointer"

FWIW, what I mean by talking through it is you explaining it to someone else. Not just "why isn't what I want to do working?" but "I think, given these conditions, and this code, I should get this result for these reasons." This way you have to document your assumptions, code, expectations and reasoning.

Often times, just going through that process will lead you to the answer yourself or with a gentle nudge from someone else.

THAT is where links I posted earlier are headed and you refuse obstinately to go.

If you want to take a dump in the pool because "that's the way you like it" that's fine. Don't expect anyone else to like it.

I LOLed.

B

Sykte
Apr 27, 2011, 07:29 PM
I have to say this thread has me captivated. First time ever..... code talk went from learning code to pooping in a pool within 3 pages.

balamw
Apr 27, 2011, 07:45 PM
I have to say this thread has me captivated. First time ever..... code talk went from learning code to pooping in a pool within 3 pages.

By this point I would have expected Nekbeth to have called us "Nazis" instead of "Pros" in order to satisfy Godwin's Law (http://en.wikipedia.org/wiki/Godwin's_law).

Which of course I have now done. :p ;)

B

Nekbeth
Apr 27, 2011, 07:49 PM
No, self refers to the instance of the object that is executing the currently running code. It is highly context dependant.

Inside a method of your view controller, yes, self refers to your view controller. Inside a method in your view object, self refers to the view object. Inside the NSTimer object, self refers to the NSTimer.

Yes, that's what I though.. I was asked the meaning of "target", so I gave an example that target:self in NSTimer refer to the timer object (one of my quiz questions), but I can't remember his name.. said that "self" refer to the controller even inside the NSTimer. That's why I said.. interesting, I mean.. all of you should know what your talking about a lot more than me. (specially Master balamw)

About the timer and how it's going... well, I really don't have time to continue to make it work, so I have postpone it for a later update. I just need to learn more about it to fix it. But hey, If you feel like giving the answer, go ahead.

The only thing that I'm missing is to restart the Timer (or use another one). Invalidating my Timer only pauses it, even = nil or releasing it, my Timer just continues where it left.

I have found a tutorial where you can start, stop and reset a timer, I could use that, but I want a datePicker to select time and the tutorial doesn't show that. Here is the link: http://www.youtube.com/watch?v=5jmTQi98vec&feature=related

Please, let me know if you need more code of the timer. I think I have share all of it.

balamw;12474773]By this point I would have expected Nekbeth to have called us "Nazis" instead of "Pros" in order to satisfy Godwin's Law (http://en.wikipedia.org/wiki/Godwin's_law).
B

that is the dumbest thing I've read in a while :p

balamw
Apr 27, 2011, 08:07 PM
I have found a tutorial where you can start, stop and reset a timer, I could use that, but I want a datePicker to select time and the tutorial doesn't show that. Here is the link: http://www.youtube.com/watch?v=5jmTQi98vec&feature=related

Divide and conquer.

Where he makes the counter count backwards from 600 by hardcoding the initial value in the label, make that a variable that is tied to the datePicker of your choice.

If you want to do it in baby steps, first use two labels one for the input and one for the display to input the starting time and then replace the input one with your datePicker.

B

KnightWRX
Apr 27, 2011, 08:08 PM
The only thing that I'm missing is to restart the Timer (or use another one). Invalidating my Timer only pauses it, even = nil or releasing it, my Timer just continues where it left.


What makes you think that ? Once you invalidate a timer, it's done and gone. Look, I implemented a timer that updates on screen with minutes:seconds and it gets reset properly when I invalidate it (take a peek at the screenshot).

A screenshot like this goes a long way. Console output with NSLog to know what gets called and when is even better.

If you posted up the full code of your viewController, we might even be able to point you in the right direction. The more you are specific, the better we can help.

I'm thinking you don't quite grasp what an NSTimer object is. It's not an actual timer as in a chicken timer. It's just an object that's inserted into the run loop, waits for a specificied interval and then calls a method (depending either the NSInvocation or the target/selector you used when creating it). If you set its repeat to YES, it will call this method over and over again at the specified interval.

This specified method (in my screenshot that would be updateLabel) has to do some processing to display minutes:seconds on a label.

balamw
Apr 27, 2011, 08:11 PM
If you posted up the full code of your viewController, we might even be able to point you in the right direction. The more you are specific, the better we can help.

Yup. Again, divide and conquer. If you don't want to share your entire code because it does something else, you don't want to reveal, pull out what is needed to demonstrate the problem into a test app to figure it out.

If you post nominally compilable code you are more likely to get to your desired answers faster.

B

Nekbeth
Apr 27, 2011, 08:19 PM
I going to do that balamw, I'll show you what I got so far in little while.

Knight , I don't know how you do it. Check my photo log, mine keeps on running.

KnightWRX
Apr 27, 2011, 08:24 PM
How do you count your elapsed ? Again, NSTimer is simply an object inserted into the run loop. It has no conception of elapsed time beyond its own internal interval.

What methods are being called and by what ? What is the code to those methods ?

You have posted bit and pieces all over the thread, why not just post a readable, compilable example of everything you have that can help us reproduce or see your actual problem ?

Nekbeth
Apr 27, 2011, 08:29 PM
I'm only posting my timer code balamw, you don't want to see the rest and even if you do, I wouldn't show it here. The only problem is the timer the rest works fine. You can check out my App tomorrow morning (Availability Date is 28 of April). Look for "Pastry Chef app"

How do you count your elapsed ? Again, NSTimer is simply an object inserted into the run loop. It has no conception of elapsed time beyond its own internal interval.

What methods are being called and by what ? What is the code to those methods ?

You have posted bit and pieces all over the thread, why not just post a readable, compilable example of everything you have that can help us reproduce or see your actual problem ?


Alright Knight, I'll show it all. Just please, if you see a problem that it's obvious to you, don't play or make trick questions, you can just explain it and I'll work it out.

balamw
Apr 27, 2011, 08:32 PM
I'm only posting my timer code balamw, you don't want to see the rest and even if you do, I wouldn't show it here. The only problem is the timer the rest works fine. You can check out my App tomorrow morning (Availability Date is 28 of April). Look for "Pastry Chef app"

Then, as I suggested above you need to pull all of that timer related code out into a "toy"/"test" app that you can post the entire code of to help us help you. As KnightWRX says we have to be able to reproduce what you are seeing to see the problem(s). This is part of the work you need to do to get help.

I don't think you are in a position to judge where it is broken, being that you don't care to understand fundamentals.

B

Nekbeth
Apr 27, 2011, 08:39 PM
.h

#import <UIKit/UIKit.h>

@interface ATimerViewController : UIViewController {

IBOutlet UIDatePicker *timePicker;

IBOutlet UILabel *label;
IBOutlet UILabel *label2;
IBOutlet UILabel *label3;

IBOutlet UIView *view1;
IBOutlet UIView *view2;

NSTimer *myTimer;
NSTimer *newTimer;

}

@property (nonatomic, retain) IBOutlet UIDatePicker *timePicker;
@property (nonatomic, retain) IBOutlet UILabel *label;
@property (nonatomic, retain) IBOutlet UILabel *label2;
@property (nonatomic, retain) IBOutlet UILabel *label3;
@property (nonatomic, retain) IBOutlet UIView *view1;
@property (nonatomic, retain) IBOutlet UIView *view2;




// MINUTES (2)
- (IBAction) echoMinute: (id) sender;
- (void) echoIt2: (NSTimer *) timer;


// SECONDS (3)
- (IBAction) echoTime: (id) sender;
- (void) echoIt: (NSTimer *) timer;


//NEW TIMER
- (IBAction) newActionTimer: (id)sender;
- (void) echoNewTimer: (NSTimer *) timer2;


// NEW PAGE
- (IBAction) nextPage: (id) sender;




@end




.m

#import "ATimerViewController.h"

@implementation ATimerViewController


@synthesize timePicker;
@synthesize label;
@synthesize label2;
@synthesize label3;
@synthesize view1;
@synthesize view2;




NSInteger seconds = 0;
NSInteger minutes = 0;



// MINUTES (2) ----------------MINUTES-----------------

- (IBAction) echoMinute:(id)sender

{

NSDate * time = timePicker.date;
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:@"HH:MM:SS"];
NSLog(@"date:%@", [dateFormatter stringFromDate:time]);
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDateComponents *comps = [gregorian components:(NSHourCalendarUnit | NSMinuteCalendarUnit) fromDate:time];

NSInteger hour = [comps hour];
NSInteger minute = [comps minute];
NSLog(@"Hour:%i", hour);
NSLog(@"minute:%i", minute);
NSInteger secs =hour * 60 * 60 + minute * 60;
NSInteger mins = secs / 60;



NSNumber *elapsedMinutes = [NSNumber numberWithInt:mins];
NSDictionary *myMinute = [NSDictionary dictionaryWithObject:elapsedMinutes forKey:@"TotalMinutes"];

[NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(echoIt2:) userInfo:myMinute repeats:YES];




label.text = [NSString stringWithFormat:@"Hours: %i, Min: %i", hour, minute]; // TIME CHOSEN (1st Label)


}



- (void) echoIt2:(NSTimer *)timer // MINUTES METHOD

{

NSNumber *num = (NSNumber *) [[timer userInfo] valueForKey:@"TotalMinutes"]; //elapsed
minutes++;

NSInteger min = [num integerValue] - minutes; //remaining
NSLog(@"elapsed: %i, remaining: %i", minutes, min);

if (min <=0)
{
[timer invalidate];
}

label2.text = [NSString stringWithFormat:@"Minutes remaining: %i", min]; // (2nd Label)

}





// SECONDS (3rd Label) ----------------SECONDS-----------------




- (IBAction) echoTime:(id)sender

{


NSDate * time = timePicker.date;
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:@"HH:MM:SS"];
NSLog(@"date:%@", [dateFormatter stringFromDate:time]);
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [gregorian components:(NSHourCalendarUnit | NSMinuteCalendarUnit) fromDate:time];

NSInteger hour = [comps hour];
NSInteger minute = [comps minute];
NSLog(@"Hour:%i", hour);
NSLog(@"minute:%i", minute);
NSInteger secs =hour * 60 * 60 + minute * 60;

NSNumber *elapsedSeconds = [NSNumber numberWithInt:secs];
NSDictionary *myDict = [NSDictionary dictionaryWithObject:elapsedSeconds forKey:@"TotalSeconds"];


myTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(echoIt:) userInfo:myDict repeats:YES];

}




- (void) echoIt:(NSTimer *)timer // SECONDS METHOD (3)

{

NSNumber *num = (NSNumber *) [[timer userInfo] valueForKey:@"TotalSeconds"]; //elapsed
seconds++;

NSInteger secs = [num integerValue] - seconds; //remaining
NSLog(@"elapsed: %i, remaining: %i", seconds, secs);

if (secs <= 0)
{
[timer invalidate];
timer = nil;

}

label3.text = [NSString stringWithFormat:@"Seconds remaining: %i", secs]; // (3rd Label)

}









//NEW TIMER ---------------- NEW TIMER -----------------


- (IBAction) newActionTimer: (id)sender
{
NSDate * time = timePicker.date;
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:@"HH:MM:SS"];
NSLog(@"date:%@", [dateFormatter stringFromDate:time]);
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDateComponents *comps = [gregorian components:(NSHourCalendarUnit | NSMinuteCalendarUnit) fromDate:time];

NSInteger hour = [comps hour];
NSInteger minute = [comps minute];
NSLog(@"Hour:%i", hour);
NSLog(@"minute:%i", minute);
NSInteger secs =hour * 60 * 60 + minute * 60;
NSInteger mins = secs / 60;



NSNumber *elapsedMinutes = [NSNumber numberWithInt:mins];
NSDictionary *myMinute = [NSDictionary dictionaryWithObject:elapsedMinutes forKey:@"TotalMinutes"];

newTimer = [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(echoNewTimer:) userInfo:myMinute repeats:NO];


}



- (void) echoNewTimer: (NSTimer *)timer2

{

[myTimer invalidate];
myTimer = nil;

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"Invalidate"
delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];

[view1 setHidden:NO];
[view2 setHidden:YES];


// is my newTimer On right now ??
}







//NEXT PAGE ---------------- NEXT PAGE -----------------


- (void) nextPage:(id)sender

{
[view1 setHidden:YES];
[view2 setHidden:NO];


}

- (void) dealloc {

[view1 release];
[view2 release];
[timePicker release];
[super dealloc];
}


@end

Divide and conquer.

Where he makes the counter count backwards from 600 by hardcoding the initial value in the label, make that a variable that is tied to the datePicker of your choice.

If you want to do it in baby steps, first use two labels one for the input and one for the display to input the starting time and then replace the input one with your datePicker.

B

Ok, This is another code from the one I posted. Nothing to do with the other.

balamw. I have set two more labels like you said to be variables of the original label (where he sets the seconds) the both do the same. Now.. because they are used both to display and to input.. I have no idea how to make one of the variables that I made tied to the datePicker. (I get warnings that say their not compatible classes).

Here is the .m :

@synthesize datePicker;
@synthesize label;
@synthesize input;
@synthesize display;




- (IBAction)start: (id)sender

{


myTicker = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(showActivity) userInfo:nil repeats:YES];
}


- (IBAction)stop

{
[myTicker invalidate];
}



- (IBAction)reset

{
label.text = @"0";


display.text = label.text;

input.text = label.text;





}



- (void)showActivity

{
int currenTime = [label.text intValue];
int newTime = currenTime + 1;
label.text = [NSString stringWithFormat:@"%d", newTime];

display.text = label.text;

input.text = label.text;


}

Cromulent
Apr 27, 2011, 10:52 PM
thats funny, as soon as someone mentions "what's a pointer"..everyone shoots to kill here, and they tell you to step out or go deep yourself in books. The last thing you'll get is a simple answer, which 1 out 20 developers give you without asking you "Have you even read the objective-C manual?? cause if not you should leave the Real Coding and go study now

Fine. I'll give you a simple answer to "What is a pointer?".

It is a memory address. Nothing more and nothing less. The reason people don't give you the simple answer is because it will mean nothing to you and you won't understand the answer until you have read the articles and documents that people have been trying to get you to read.

Frankly having read this thread I think your behaviour is disgusting. People have been falling over themselves here trying to help you and you are just dismissing every single piece of help that is being offered to you.

Nekbeth
Apr 28, 2011, 12:06 AM
Here we go with same old stuff..

And what makes you thing a simple answer doesn't mean anything to me? I get a lot of simple "direct" answers that have help me in the Apple Forum but If your so disgusted and sensitive, feel free to leave the thread, some people do want to help here.

This is almost like a Chess game, if I say that I have read Stephen G. Kochan's book, the beginning iPhone SDK programming with objective-c, Pro core data for OS, beginning iPHone development, the developers cookbook, Masters of the void and so on, as well as watch many iTunes U and WWDC videos... you know what many here are will say ?? how about " well then you should read them all over again or any x, y thing..

the point is.. you can't never fulfill peoples expectations and that applies to anything, not just programming. So, follow your way I say (theres no limitations there). My state of newbie or dummy if you want to call it, is temporary, just like any Pro was but you already get an idea of who's willing to help you and who just wants to play with you.

KnightWRX
Apr 28, 2011, 04:27 AM
Look, your attitude really needs some adjustment Nekbeth. I have not asked a single trick question. My questions have all been about trying to understand what it is you're trying to do and what problems you are facing. You have been less than clear this whole time.

I think part of that problem is that you're thinking "I'm a newbie, these guys are pros, I'll probably get help but end up being laughed at". Seriously, if I want to laugh at people, I'll just head over to the news discussion. Those guys are a riot. And I'm not a pro at all. Sure I've been doing this for 15 some odd years in one form or another, but never as a job, only as a hobby.

The programming forum is full of newbies. I was a newbie once too. We all start somewhere and it's no laughing matter. I wouldn't spend all this time trying to figure out what it is you're doing wrong if it was only to laugh at you in the end.

Relax and try to realise we want to help you, otherwise we wouldn't be posting here. Now listen to us. We need your help too. As Pros, there are things we know that you might not, and you need to be clear and specific about your problem and what you're not understanding.

Now I'll try to take a look at the code you posted (I just got up and I need to get to work) and see if I can dig out something if someone doesn't do it faster than me.

Jethrotoe
Apr 28, 2011, 06:07 AM
I must say, I have never seen a more patient group of mentors in my life.
Hats off to ya. You are all great. I've learned volumes reading your posts.

And thank you.

KnightWRX
Apr 28, 2011, 06:34 AM
Nekbeth, I'm looking at the code and I'm thinking you still don't quite understand what NSTimer is and does. You keep track of "Elapsed" using 2 implementation scope global variables :


NSInteger seconds = 0;
NSInteger minutes = 0;


However, grepping for these variables, you never reset them back to 0 aside from their initial initialization :


$ grep -e minutes -e seconds ATimerViewController.m
NSInteger seconds = 0;
NSInteger minutes = 0;
minutes++;
NSInteger min = [num integerValue] - minutes;
NSLog(@"elapsed: %i, remaining: %i", minutes, min);
seconds++;
NSInteger secs = [num integerValue] - seconds;
NSLog(@"elapsed: %i, remaining: %i", seconds, secs);


Your minutes and seconds are thus never reset, so your "timer" is never reset (this is completely a seperate issue from NSTimer, hence why I say you probably don't understand the scope of NSTimer. It has no knowledge of these variables and thus doesn't reset them when you invalidate myTimer or newTimer).

Also, could you please post a screenshot of your Interface Builder associations ? (under File's Owner, the tab in Inspector with all the Outlets and Actions), because I can't quite figure out what buttons are tied to what actions.

You also still have 2 timers. Why do you believe you need both ? Have you tried simplifying the code to using only 1 ?

None of these are trick questions, It's me trying to understand what you think this code should do vs what it's actually doing. Now, if you don't answer my questions, I can't really help you here short of writing the code for you, which does not help you learn (I have a good idea how to make the code I wrote last night do what you want to do very quickly, but I doubt you can afford me as a consultant at my exorbitant rates!).

Nekbeth
Apr 28, 2011, 09:12 AM
Thanks Knight, you are one of those who does helps no matter what, so I appreciate your patience, like Jethrotoe said. So, please don't take everything I typed and generalize it, because it's not for everyone. You personally look into the problem, ask questions about what's going on.. that is good !!, some other don't have your patience and throw in the typical sentence " Go learn fundamentals and come back" as soon as they see a basic mistake. So Patience I think is the right word to describe what's been going on here. It is actually a virtue and a basic one for a teacher to have.

Back to the code, here is a photo of my connections (ignore canceBigtimer). What you say is true I don't know how NSTimer works entirely , just some parts, I realize that and it is one of the reason I postpone my timer for a future update (need to study it).

You mention my two global variables, It makes sense that the timer does not stop because the variables are outside the method that creates the timer. is that whats going on?

I have two timers, because, like I said.. I don't have full knowledge of timers. I know now that 1 timer is enough, even if I use two timers and start them at the same time, the log only shows 1 loop and the countdown in separate labels show e.g. 59 in one and 58 in another and so on.

I got confuse because some other forums told me that I should make 2 timers.

It's ok, I never ask for code, I leave that to the person. You have pointed out a big mistake on my part already and that is more than I can ask. This code is actually from a follow up tutorial in one of my books to learn NSTimer, the name of the book is "iPhone SDK Programming, A Beginner's Guide ", after the book explains everything and the code is working, it doesn't tell you how to stop it, reset it or add minutes to it, and that is why I wanted to complete what was left from this book.

wlh99
Apr 28, 2011, 09:13 AM
Your minutes and seconds are thus never reset, so your "timer" is never reset (this is completely a seperate issue from NSTimer, hence why I say you probably don't understand the scope of NSTimer. It has no knowledge of these variables and thus doesn't reset them when you invalidate myTimer or newTimer).


That has been pointed out. The OP is stuck thinking the timer is broken, when it works exactly as it should. I think the OP thinks that those variables are part of the timer. He also first thought "self" was the timer. I asked if/where he was resetting the seconds, and if he wanted a reset function or not. For all we know, he wants a start stop timer that doesn't reset. That would be a normal implementation.


Also, could you please post a screenshot of your Interface Builder associations ? (under File's Owner, the tab in Inspector with all the Outlets and Actions), because I can't quite figure out what buttons are tied to what actions.

That would be very helpful. Also, explain how you want the program to act as the user uses it.


You also still have 2 timers. Why do you believe you need both ? Have you tried simplifying the code to using only 1 ?

He was told elsewhere that he could not reuse a timer. I think he is still stuck on the concept (not necessarily the definition) of a pointer, and of the life-cycle of an object. I'm not sure he grasps that in the posted samples, the NSTimer was not being reused.


None of these are trick questions, It's me trying to understand what you think this code should do vs what it's actually doing. Now, if you don't answer my questions, I can't really help you here short of writing the code for you, which does not help you learn (I have a good idea how to make the code I wrote last night do what you want to do very quickly, but I doubt you can afford me as a consultant at my exorbitant rates!).


I have some code to post to help the OP. But for not, I'm about to get a parking ticket, so I have to leave. But I will post it today.

Nekbeth
Apr 28, 2011, 09:38 AM
wlh99, let me tell you precisely what I want to achieve, so there is no more confusion.

Two views;

View 1 is the ticker and a button underneath (button start.

View 2 is display (label) with the timer running and a button underneath (button Cancel)

Button Cancel will have two maybe three funtions ( stop the timer, reset it or just reset it at once and call View1 so the user can reuse the timer over again. That's it, I want to add that function to my App for 1.1 or it could be 1.4 if don't get to study now hahaa.

I'll take care of the alarms, sounds and those details if it reaches to zero, that I know already.

By the way, what's with 3rd person reference? the OP? you can call me Nekbeth or Chrystian, it's a lot more polite. Maybe you guys have a way to refer to someone , I don't know.

KnightWRX
Apr 28, 2011, 09:42 AM
So, please don't take everything I typed and generalize it, because it's not for everyone.

I do understand where Dejo, Balamw and the others are coming from though. And frankly, they are probably better suited to help you than I am. I don't have a lot of experience with Objective-C and Cocoa, not like they do, having mostly come into it recently.

Back to the code, here is a photo of my connections (ignore canceBigtimer). What you say is true I don't know how NSTimer works entirely , just some parts, I realize that and it is one of the reason I postpone my timer for a future update (need to study it).

I have two timers, because, like I said.. I don't have full knowledge of timers. I know now that 1 timer is enough, even if I use two timers and start them at the same time, the log only shows 1 loop and the countdown in separate labels show e.g. 59 in one and 58 in another and so on.

Ok, how about we work on making 1 timer work then ? The code you posted is very complicated and I don't think it has to be this complicated. Going 1 timer would simplify this.

I see your Start Button is associated to 3 actions. Is this really what you want ? Let's simplify this. As an exercise, make 1 method, call it startTimer (like I did) and have only that action associated with your start button. From there, you can call the other methods yourself as needed.

Once you have modified the code in this way, post again what you have in full, what it is doing and what you think it should be doing. We'll go from there.

You mention my two global variables, It makes sense that the timer does not stop because the variables are outside the method that creates the timer. is that whats going on?

No, the variables are "fine" where they are. They would be better positionned in the @interface block and declared as instance variables, but implementation scope globals work too.

What you need to do however is reset those if you want your timer to start back at 0. Somewhere in your "stop/reset" code, there needs to be an initialization of those back to 0 :

seconds = 0;
minutes = 0;

If your Cancel button is what should reset it, then this should be right now in newActionTimer. But ideally, we'll get rid of that function when you simplify the code down to 1 timer.

Look at my NSLog outputs in my screenshot earlier. There's 3 methods there. updateLabel, cancelTimer, startTimer. This should have given you a big indication of how not complicated you should have made this.

If you want 3 buttons, start, reset, stop, you'd technically need 4 methods, as follows :

-(IBAction) startTimer: (id) sender;
-(IBAction) stopTimer: (id) sender;
-(IBAction) resetTimer: (id) sender;
-(void) updateLabel;


One to update the label as needed, one to start the timer, one to stop it and one to reset it.

Also, NSTimer is not your timer. The timer is what you are creating with ATimerViewController. You need to grasp this. NSTimer simply calls methods, in this case, it should be update label. That's about all it should be doing. Both the stop and reset methods should release the NSTimer object instance. startTimer should always create a new one. However, reset should be the one to set back seconds/minutes to 0.

Nekbeth
Apr 28, 2011, 10:00 AM
That's a very good explanation Knight, I'm starting to understand some things better. Let me go do some stuff (eat, banks, etc) and I'll post an updated code with the startTimer method you mention and continue with that 1 timer. I'll be back soon.

Thank you once again

wlh99
Apr 28, 2011, 10:08 AM
By the way, what's with 3rd person reference? the OP? you can call me Nekbeth or Chrystian, it's a lot more polite. Maybe you guys have a way to refer to someone , I don't know.

I appologize for that. I didn't recall your name. I was replying to KnightWRX, so I took a shorcut (original poster).

I won't do that any further.

I through together a simple program that I think does exactly as you want. It is a Mac version, but the different there is trival, and instead of a picker, it is a text field the user enters a time into for the timer duration. You will need to change the NSTextFields into UITextFields.

The bulk of the code is exactly what I posted before, but I modified the EchoIt method to work with an NSDate. I implemeted it in the appDelegate, and you are using your viewController. That doesn't change the code any, and your way is more correct.

I can email you the whole project as a zip if you want. It is about 2.5 meg. Just PM me your email address.


//
// timertestAppDelegate.m
// timertest
//
// Created by Warren Holybee on 4/27/11.
// Copyright 2011 Warren Holybee. All rights reserved.
//

#import "timertestAppDelegate.h"

@implementation timertestAppDelegate

@synthesize window, timeTextField, elapsedTimeTextField, timeLeftTextField;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
}

-(IBAction)startButton:(id) sender {
// myTimer is declared in header file ...

if (myTimer!=nil) { // if the pointer already points to a timer, you don't want to
//create a second one without stoping and destroying the first

[myTimer invalidate];
[myTimer release];
[startDate release];
}

// Now that we know myTimer doesn't point to a timer already..

startDate = [[NSDate date] retain]; // remember what time this timer is created and started
// so we can calculate elapsed time later


NSTimeInterval myTimeInterval = 0.1; // How often the timer fires.
myTimer = [NSTimer scheduledTimerWithTimeInterval:myTimeInterval target:self selector:@selector(echoIt)
userInfo:nil repeats:YES];
[myTimer retain];
}

-(IBAction)cancelIt:(id) sender {
[myTimer invalidate];
[myTimer release]; // This timer is now gone, and you won't reuse it.
myTimer = nil;
}

-(void)echoIt {


NSDate *now = [[NSDate date] retain]; // Get the current time
NSTimeInterval elapsedTime = [now timeIntervalSinceDate:startDate]; // compare the current time to
[now release]; // our remembered time

NSLog(@"Elapsed Time = %.1f",elapsedTime); // log it and display it in a textField
[elapsedTimeTextField setStringValue:[NSString stringWithFormat:@"%.1f",elapsedTime]];

float timeValue = [timeTextField floatValue]; // timeValueTextField is where a user
// enters the countdown length

float timeLeft = timeValue - elapsedTime; // Calculate How much time is left.
NSLog(@"Time Left = %.1f",timeLeft); // log it and display it
[timeLeftTextField setStringValue:[NSString stringWithFormat:@"%.1f",timeLeft]];

if (timeLeft < 0) { // if the time is up, send "cancelIt:"
[self cancelIt:self]; // message to ourself.
}


}




@end


*edit:
If you like, later tonight I can show you how to do this as you first tried, by incrementing a seconds variable. Or wait for KnightWRX. My concern is accuracy of the timer. It might be off by several seconds after running an hour. That might not be an issue for your application, but you should be aware of it.

KnightWRX
Apr 28, 2011, 10:17 AM
*edit:
If you like, later tonight I can show you how to do this as you first tried, by incrementing a seconds variable. Or wait for KnightWRX. My concern is accuracy of the timer. It might be off by several seconds after running an hour. That might not be an issue for your application, but you should be aware of it.

No, it very much is an issue, but I think this is an issue we should look into after the "timer" portion is working.

If we have a skeleton of a "timer" application working, with start/stop/resets going and a display that updates properly, then changing variables we increment based on the NSTimer firing to variables we increment based on the system clock is a trivial change.

Nekbeth
Apr 28, 2011, 11:42 AM
No problem wlh99, it's alright. Guys, it turns out that today mmm... how do you say that in English ?? oh yeah, today I'm moving out of my house and I'll be busy most of the day but I hope I can work on that timer later in the afternoon (it's now 11 am here), I'll post it right away.

cheers,

wlh99, my e-mail is chryshiram@gmail.com

thanks

Nekbeth
Apr 28, 2011, 05:48 PM
Ok fellows, thanks for the waiting, my new house is a mess but at least all my furniture is here now. I follow both of your examples ( wlh99's E-mail project and the great explanation that Knight showed here). I first started a new project in order to avoid confusion and made some changes, the result is what I think " a working timer " with start, stop and reset buttons. If I see the code now it seems a bit obvious why the timer never stopped before. I can tell you right now that I never reset the global variables inside any cancel or reset button thus the timer always continued. I think that the first variable (NSInteger seconds = 0 before the first method) gets called only once after that we reset it to 0 using the reset or cancel method (we can do it separately like knight said), in my case I assign reset to be the one to set that to 0 and cancel to invalid the timer.

Knight and wh99, if you like to see the project running and tell me your throughs, just give me your E-mail addresses (I have Warren's already) so I can share it with you. For obvious reasons I'm not posting it and if some of you wonder why, it's for same reasons nobody posted the complete working code despite being able to make a timer in less than 3 minutes. (yes, I know it's because you think it would not help me and I understand)

Special thanks to Knight and wh99 for their patience and instructions.

Thanks also to everyone who gave his opinion on this matter.

* Here is photo of the log and UI

balamw
Apr 28, 2011, 07:37 PM
I first started a new project in order to avoid confusion and made some changes, the result is what I think " a working timer " with start, stop and reset buttons.


Maybe now you can go back and realize that you could have saved yourself and the rest of us a lot of time and effort by adhering to the recommendations from the links I posted. (Seriously, read them.)

Be specific. Be complete. Post complete, compilable code that demonstrates your problem. (If you need to, make a separate toy app, divide and conquer).

This is part of the "step back" that everyone was telling you to do early on, and is a basic skill for all kinds of troubleshooting. By breaking down the problem and explaining it to someone else you will often get an epiphany of your own. Like:
If I see the code now it seems a bit obvious why the timer never stopped before.
If the solution was handed to you it wouldn't (a) be that obvious [because you wouldn't understand it] and (b) wouldn't be exactly what you want.


For obvious reasons I'm not posting it and if some of you wonder why, it's for same reasons nobody posted the complete working code despite being able to make a timer in less than 3 minutes. (yes, I know it's because you think it would not help me and I understand)


I still don't think you understand the give and take of being a full participant in a forum like this.

It's your choice alone whether to add to the general knowledge pool or not. That's very different than responding to an ill-defined request for code.

For example, here's a thread I started earlier this month: http://forums.macrumors.com/showthread.php?t=1133446 I was playing with some code from various tutorials that was no longer functional, found a way to fix it and chose to give that solution back to the 'net and it was immediately useful for another user.

B

Nekbeth
Apr 28, 2011, 09:31 PM
For example, here's a thread I started earlier this month: http://forums.macrumors.com/showthread.php?t=1133446 I was playing with some code from various tutorials that was no longer functional, found a way to fix it and chose to give that solution back to the 'net and it was immediately useful for another user.
B

That is good balamw, very good of your part to give back. But I decided to give back to only those who stayed with me to the End and showed true patience. Besides, this code is a piece of cake for all you.

*If your a beginner, just send me an E-mail and I will help you, PATIENTLY.

wlh99
Apr 29, 2011, 10:52 AM
Ok fellows, thanks for the waiting, my new house is a mess but at least all my furniture is here now. I follow both of your examples ( wlh99's E-mail project and the great explanation that Knight showed here). I first started a new project in order to avoid confusion and made some changes, the result is what I think " a working timer " with start, stop and reset buttons. If I see the code now it seems a bit obvious why the timer never stopped before. I can tell you right now that I never reset the global variables inside any cancel or reset button thus the timer always continued. I think that the first variable (NSInteger seconds = 0 before the first method) gets called only once after that we reset it to 0 using the reset or cancel method (we can do it separately like knight said), in my case I assign reset to be the one to set that to 0 and cancel to invalid the timer.

Knight and wh99, if you like to see the project running and tell me your throughs, just give me your E-mail addresses (I have Warren's already) so I can share it with you. For obvious reasons I'm not posting it and if some of you wonder why, it's for same reasons nobody posted the complete working code despite being able to make a timer in less than 3 minutes. (yes, I know it's because you think it would not help me and I understand)

Special thanks to Knight and wh99 for their patience and instructions.

Thanks also to everyone who gave his opinion on this matter.

* Here is photo of the log and UI

Glad you got it working. Trust me when I say, it is not obvious, and that it now seems so to you is an accomplishment.