【问题标题】:pass info from Model to viewController without NSNotification在没有 NSNotification 的情况下将信息从模型传递到 viewController
【发布时间】:2014-06-11 20:24:31
【问题描述】:

在我的 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?

【问题讨论】:

  • 也许delegate 会解决这个问题?
  • 使用块方法(回调方法)。在 Timer 类(模型)中创建一个以黑色为参数的方法,并在视图控制器中调用它。这样,一旦计时器类方法执行完毕,它将再次将控制权返回给视图控制器类,并使用该方法所需的值。 developer.apple.com/library/ios/documentation/Cocoa/Conceptual/…
  • @TechNet-Weblineindia 感谢您的建议。我对积木不是很有经验,无法让它工作。你能看一下我所做的更新并提出一些建议吗?

标签: ios objective-c


【解决方案1】:

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

在 Timer 类中,创建一个块

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类中,调用定时器启动方法如下

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-29
    • 2018-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-01
    相关资源
    最近更新 更多