Marcelo
Marcelo

Reputation: 1206

Sending Notifications from Model to Controller in iOS

I made a class, called Timer. Its designated initializer starts a timer with a value in seconds. It works great. However I am having trouble updating the controller w/e the timer ticks.

Right now, for every tick I am sending a NSNotificationCenter with a userInfo that is a simple dictionary with the current time, which does not sound the best way to do it...

NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:self.timerCount] forKey:@"timerCount"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"TimerCountChanged"
                                                    object:self
                                                  userInfo:dict];

Should I be using some other technique or am I doing it the right way?

Thank you in advance!

EDIT: I need to initialize different Timers, using different values. I tried to use Delegates, but I only had one method in my controller to update the UI for all those Timers! Would it be bad if I do something like? Passing a UIButton to my Model also does not seem to be the best solution but it works.

-(void)timer:(Timer *)timer didTriggerAt:(NSTimeInterval)time andButton:(UIButton *)button
{
        [button setTitle:[NSString stringWithFormat:@"%.0f", time] forState:UIControlStateNormal];
}

- (IBAction)startCountDown:(UIButton *)sender
{    
    self.timer1 = [[Timer alloc] initWithTimeInSeconds:10 andButton:sender];
    self.timer1.delegate = self;
}

I have 3 Timers in my MainView, the user can start them whenever he wants. They can also have different times, which is also defined by the user.

Upvotes: 0

Views: 836

Answers (2)

Anoop Vaidya
Anoop Vaidya

Reputation: 46563

Sending Notifications is good, but you may not observe it as in regular time.

Sometimes it gets delayed and you may observe them in irregular time interval.

You can use

  1. Delegate Pattern.

  2. Call method by selector

EDIT:

From

Apple documentation on Performance CodeSpeed on Notifications.

The fewer notifications you send, the smaller the impact on your application’s performance. Depending on the implementation, the cost to dispatch a single notification could be very high. For example, in the case of Core Foundation and Cocoa notifications, the code that posts a notification must wait until all observers finish processing the notification. If there are numerous observers, or each performs a significant amount of work, the delay could be significant.

Upvotes: 2

tom
tom

Reputation: 19173

If you only have one client object for each Timer instance, then you should use the delegate pattern. You would define a TimerDelegate protocol with a method that a Timer object can call whenever the timer ticks.

e.g.

@class Timer;

@protocol TimerDelegate
- (void) timer:(Timer *)timer didTriggerAt:(NSTimeInterval)time;
@end

@interface Timer
...
@property (assign) id<TimerDelegate> delegate;
...
@end

If you indeed require multiple listeners each time a Timer instance ticks, then the NSNotificationCenter approach would be a better fit. Instead of passing info in the userInfo dictionary, I probably would expose an @property on Timer called currentTime, so that when a client object gets the notification, they could simply access currentTime on the notifying Timer, instead of (IMO clunkily) reading data out of userInfo.

Upvotes: 0

Related Questions