【问题标题】:To which source file does NSRunLoop/NSTimer belong?NSRunLoop/NSTimer 属于哪个源文件?
【发布时间】:2011-03-29 11:59:48
【问题描述】:

我一直在试图弄清楚如何设置 NSTimer 以允许我在视图中的 UILabel 中打印当前时间,并让它每秒更新一次(不需要更精细的分辨率 - 只需一个简单的时钟)。

起初,我没有使用 NSRunLoop,但如果我尝试包含一个,则执行只会在循环内“旋转”,从而阻止进一步的执行。我已经在下面发布了我的代码。

-(id) printCurrentTime {

now = [NSDate date];
dateFormat = [[NSDateFormatter alloc] init];

[dateFormat setTimeStyle:NSDateFormatterMediumStyle];

NSString *nowstr = [dateFormat stringFromDate:now];
[dateFormat release];
NSLog(@"Current time is: %@",nowstr);

return nowstr;
}

在 ViewController 源文件中,我按如下方式执行:

TimeStuff *T = [[TimeStuff alloc] init];
NSString *thetime = [T printCurrentTime];
[timelabel setText:thetime];
[T release];
[self.view addSubview:timelabel];


NSTimer *timmeh = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(printCurrentTime) userInfo:nil repeats:YES];

[[[NSRunLoop currentRunLoop] addTimer:timmeh forMode:NSDefaultRunLoopMode] run];

“TimeStuff”类实际上是一个空类,除了 printCurrentTime 函数。

问题:

1) 我应该在 AppDelegate 类中包含 RunLoop 吗?我无法想象这一切应该如何结合在一起,例如 - 实现基于 Timer 的循环以最多秒更新文本标签的步骤是什么。好难过。

2) 如果我应该使用 NSThread,那也应该在它自己的类/Delegate 类中。

3) ViewController 类是否完全超出了循环/计时器的范围,只是“眼睛糖果”类,带有对 Delegate 类中函数的回调?

感谢您的时间和耐心。

【问题讨论】:

    标签: iphone objective-c


    【解决方案1】:

    您根本不需要处理运行循环。

    这一行:

    NSTimer *timmeh = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(printCurrentTime) userInfo:nil repeats:YES];
    

    将为您创建一个计时器并将其附加到当前线程的运行循环。您根本不需要 [NSRunLoop addTimer:forMode:] 调用 - 您可以删除该行。

    PS 你当然不需要到 NSThreads 这么远!


    编辑关于您的评论:

    如果您的 printCurrentTime 方法所在的位置,您将需要创建 TimeStuff 类的实例以供计时器使用。即

    @interface MyViewController : UIViewcontroller {
        TimeStuff *timeStuff
    }
    

    在你的 viewDidLoad 方法中:

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        ...
    
        // Create our timestuff if we don't have one already
        if (nil == timeStuff)
            timeStuff = [[TimeStuff alloc] init];
    
        // Start the timer
        [NSTimer scheduledTimerWithTimeInterval:1.0 target:timeStuff selector:@selector(printCurrentTime) userInfo:nil repeats:YES];
    

    别忘了dealloc

    - (void)dealloc {
        [timeStuff release];
        ...
        [super dealloc];
    }
    

    传入 timeStuff 作为计时器的目标,告诉它在哪里寻找 printCurrentTime 方法!

    希望对你有帮助,

    PS @class TimeStuff 的所有行都是告诉编译器有一个名为 TimeStuff 的类。它不知道您想将它用作计时器的选择器!

    【讨论】:

    • 您好,感谢您的指导。我按照建议实现了,但我得到了“发送到实例的无法识别的选择器”和一个 SIGABRT。选择器的范围是什么?文件范围?我在另一个类文件 (TimeStuff.m) 中实现了实际的函数 printCurrentTime,尽管包括“@class TimeStuff;”在 ViewController 类文件中(顺便说一句,是 NSTimer 所在的位置 - 在 vi​​ewDidLoad: 方法中),我仍然收到此错误。任何的想法? -- 谢谢
    • 选择器的作用域是target参数!如果你传入self 作为目标,那么选择器必须是当前类的方法。您应该传入 TimeStuff 类的实例作为目标。
    • 查看我编辑的问题以获得对您评论的更清晰答案 - 我总是更喜欢一个例子而不是一段文字!
    • 嗨,院长,再次感谢您的详细回答!我已经采纳了你的建议,但无济于事。我仍然得到未知的选择器。我认为因为我没有粘贴整个代码库,所以它遗漏了一些可能很重要的东西。我想我会从一个原始的命令行项目重新开始,然后尝试让一个简单的计时器工作,然后从那里开始工作。我可以看到您的建议在范围方面非常有意义,并且由于您的简洁帮助,我可以理解我哪里出错了。干杯!
    • 没问题,希望你能成功!如果您有任何其他问题,请不要犹豫:)
    猜你喜欢
    • 1970-01-01
    • 2013-03-28
    • 1970-01-01
    • 2015-11-28
    • 1970-01-01
    • 1970-01-01
    • 2010-11-10
    • 1970-01-01
    • 2016-12-01
    相关资源
    最近更新 更多