Search code examples
objective-ccallbackclockdelegation

Simple Clock application: use delegation or callback every second?


I'm having some fun with objective c. As a simple program I wanted to write a clock application.

Basically, a UITextField needs to show the current time and update every second.

My initial thought was to use delegation and let UITextField call back a class when the 'Value Changed' event occurs. By 'bootstrapping' an initial value change (e.g. by setting the time at application startup) I thought I could trigger the 'Value Changed' event continuously afterwards (the UITextField would continuously change itself, hence triggering the delegate method). I tried many things, but this never worked. I even tried creating a button that would set UITextField to an arbitrary text value (as opposed to setting UITextField at startup) in the hope that the delegated method would be called, but this did not either. To prove that my code was correct, the time was updated when I'd use other actions like 'Touch Down' for example: I would get the time on every click in the UITextField.

I eventually found out that i could use a callback every second by using [self performSelector ...] and that worked.

Is there a fundamental reason my delegation using the 'Value Changed' action never worked ?


Solution

  • The value changed event only fires in response to a user event-- that is, you setting your textField.text = "something" doesn't fire it, by design.

    And it's a good job it doesn't, because by the sounds of it you were trying to get your application into an infinite loop. If the 'value changed' event did actually fire when you set the text in the box, the program would ask the delegate again, which would set the text again, which would ask the delegate again..... you get the picture. This is called an infinite loop, and it has the effect of causing the program to hang, and then crash, since there's no way for the program execution to exit this loop.

    Anyway, in order to do what you're saying, you've got two options

    1. you can set up an NSTimer object to call your time update method every second. It's quite easy, check out the documentation.

    2. performSelector:withObject:afterDelay:. It sounds like you might have already got the hang of this one. It's not as neat as using an NSTimer, but it will do the job.