将信息从Model传递给没有NSNotification的viewController

时间:2014-04-25 23:27:13

标签: ios objective-c

在我的viewController中,我有一个按钮,它调用一个方法来启动Timer类中的计时器。就像这样

主视图控制器

[self.timer startTimer];

在计时器课程中,startTimer会调用countdownTime方法,您可以在下面看到这两种方法。非常简单。在countdownTime方法结束时,时间放在视图中的标签中,就像我遍历时钟循环一样。

 Timer *timerblah = self.gameClocks[i];
 [self.gameClocks[i] setText: [NSString stringWithFormat:@"%@", self.time]];

换句话说,Timer类有一个数组属性,它保存所有时钟并连接到视图,因此能够设置文本。

此代码的问题在于模型(即Timer类)正在视图中设置文本。我希望视图控制器从模型中获取时间并在视图控制器中设置文本,即具有viewController并且只有viewController与视图通信。在viewController中获取时钟数组对我没有问题,但是,我确定如何将时间从countdownTime方法传递回viewController。设置一个NSNotification类来每秒发回时间似乎有点过头了,不是吗?

 -(void)startTimer{
    self.NStimer = [NSTimer scheduledTimerWithTimeInterval:1.0
                                                    target:self
                                                  selector:@selector(countdownTime:)
                                                  userInfo:nil
                                                   repeats:YES];
}

-(void)countdownTime:(NSTimer *)timer
{
    #logic to countdown time
    self.minutes = self.secondsRemaining / 60;
    self.stringMinutes = [NSString stringWithFormat:@"%i", self.minutes];
    self.seconds = self.secondsRemaining - (self.minutes * 60);
    self.stringSeconds = [NSString stringWithFormat:@"%i", self.seconds];

    if (self.seconds < 10) self.stringSeconds = [NSString stringWithFormat:@"0%i", self.seconds];
    self.time = [NSString stringWithFormat:@"%@:%@", self.stringMinutes, self.stringSeconds];
    self.secondsRemaining -= 1;
    if (self.secondsRemaining == 0){
        [self stopTimer];
    }

    #adding to the view (from the model i.e. in Timer.m class)
    for(int i = 0; i < [self.gameClocks count]; i++){
            Timer *timerblah = self.gameClocks[i];
            if (timerblah.systemClock == YES){
            [self.gameClocks[i] setText: [NSString stringWithFormat:@"%@", self.time]];
            }
        }

}

更新

有评论建议我使用一个块来做到这一点。在timer类中,我添加了一个这样的方法来返回一个带时间的字符串(时间设置为self.time)

-(NSString *)passTheTime:(NSString (^)(void))returnBlock

{
    return self.time;
}

然后,在视图控制器中,在计时器类上调用方法passTheTime。我在视图控制器中创建了一个存储时间的属性,因此我将其作为参数传递给块

 [self.timer passTheFoo:^NSString * (self.timeToSet){

        }];

a)我不确定在这个街区做什么。

b)我不确定是否有必要将self.timeToSet传递给该区块。如何将Timer类中的self.time连接到视图控制器中的self.timeToSet

c)出现错误incompatible block pointer type sending NSString *((^)(void)) to parameter of type NSString(^)(void)

d)或者,我可以将一个块传递给startTimer,并在选择器countdownTime中传递该块,并在countdownTime中的计算完成后返回self.time吗?

1 个答案:

答案 0 :(得分:0)

您可以使用block更新视图控制器类中的标签,如下所示

在Timer Class中,创建一个块

TimerClass.h

#import <Foundation/Foundation.h>


typedef void(^TimerCallback)(NSString *time); 

@interface TimerClass : NSObject{

    TimerCallback timerCallback;
    NSTimer     *timer;
}

- (void)startTimerWithCallBack:(TimerCallback)callback;

@end

在TimerClass.m中,更新代码如下

 #import "TimerClass.h"

    @implementation TimerClass


    - (void)startTimerWithCallBack:(TimerCallback)callback{

        timerCallback = callback;

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


    -(void)countdownTime:(NSTimer *)timer
    {

        // countdown logic here

        // call the callback method with time as a parameter to the viewcontroller class

        // here for demo purpose I am passing random number as a value in callback, you need to pass the time that you want to display here
        NSString *str = [NSString stringWithFormat:@"%d",1+arc4random()%10];

        timerCallback(str);

    }

    @end

在ViewController类中,按如下方式调用timer start方法

TimerClass *timer = [[TimerClass alloc] init];
    [timer startTimerWithCallBack:^(NSString *time) {
        lbl.text = time; // display time in label
    }];