在 iOS 上使用多个 NSTimer - 仅触发一个计时器

发布于 2024-10-29 09:32:07 字数 1932 浏览 1 评论 0原文

需要帮助解决问题。

目标
我正在编写一个 iOS 图书应用程序,它使用 NSTimers 在加载视图后触发几个交错的动画事件。我创建了一个 MethodCallerWithTimer 类来帮助我做到这一点(代码在底部)。

到目前为止我的解决方案
当我使用 MethodCallerWithTimer 类时,我将 objectOwningMethod 分配为我的 UIViewController 子类对象(它是一个书页),然后将该方法分配为该类中的实例方法。这是我分配的方法的示例 - 非常简单地打开屏幕上的一些艺术品:

- (void) playEmory {
   [emoryRedArt setHidden:NO];
}

我的问题
当我创建多个 MethodCallerWithTimer 实例然后加载视图并启动它们时,我只会发生第一个事件。其他计时器均不会调用其目标方法。我怀疑我不明白我要求 NSRunLoop 做什么或类似的事情。

有什么想法吗?

这是我的 MethodCallerWithTimer 类:

@interface MethodCallerWithTimer : NSObject {
    NSTimer * timer;
    NSInvocation * methodInvocationObject;
    NSNumber * timeLengthInMS;
}

- (id) initWithObject: (id) objectOwningMethod AndMethodToCall: (SEL) method;
- (void) setTime: (int) milliseconds;
- (void) startTimer;
- (void) cancelTimer;

@end

和实现:

#import "MethodCallerWithTimer.h"

@implementation MethodCallerWithTimer

- (id) initWithObject: (id) objectOwningMethod AndMethodToCall: (SEL) method {
    NSMethodSignature * methSig = [[objectOwningMethod class] instanceMethodSignatureForSelector:method];
    methodInvocationObject = [NSInvocation invocationWithMethodSignature:methSig];
    [methodInvocationObject setTarget:objectOwningMethod];
    [methodInvocationObject setSelector:method];
    [methSig release];
    return [super init];
}
- (void) setTime: (int) milliseconds {
    timeLengthInMS = [[NSNumber alloc] initWithInt:milliseconds];
}
- (void) startTimer {
    timer = [NSTimer scheduledTimerWithTimeInterval:([timeLengthInMS longValue]*0.001) invocation:methodInvocationObject repeats:NO];
}
- (void) cancelTimer {
    [timer invalidate];
}
-(void) dealloc {
    [timer release];
    [methodInvocationObject release];
    [timeLengthInMS release];
    [super dealloc];
}

@end

Need help with a problem.

Goal
I'm putting together an iOS book app that uses NSTimers to fire off several staggered animation events after loading a view. I've created a MethodCallerWithTimer class to help me do this (code at bottom).

My Solution So Far
When I use the MethodCallerWithTimer class, I assign the objectOwningMethod as my UIViewController subclass object (it's a book page), and then the method as an instance method in that class. Here is an example of a method I assign - quite simply turning on some artwork on the screen:

- (void) playEmory {
   [emoryRedArt setHidden:NO];
}

My Issue
When I create multiple MethodCallerWithTimer instances then load the view and start them all, I only ever get the FIRST event to happen. None of the other timers call their target methods. I suspect I don't understand what I'm asking NSRunLoop to do or something similar.

Any thoughts?

Here is my MethodCallerWithTimer class:

@interface MethodCallerWithTimer : NSObject {
    NSTimer * timer;
    NSInvocation * methodInvocationObject;
    NSNumber * timeLengthInMS;
}

- (id) initWithObject: (id) objectOwningMethod AndMethodToCall: (SEL) method;
- (void) setTime: (int) milliseconds;
- (void) startTimer;
- (void) cancelTimer;

@end

And implementation:

#import "MethodCallerWithTimer.h"

@implementation MethodCallerWithTimer

- (id) initWithObject: (id) objectOwningMethod AndMethodToCall: (SEL) method {
    NSMethodSignature * methSig = [[objectOwningMethod class] instanceMethodSignatureForSelector:method];
    methodInvocationObject = [NSInvocation invocationWithMethodSignature:methSig];
    [methodInvocationObject setTarget:objectOwningMethod];
    [methodInvocationObject setSelector:method];
    [methSig release];
    return [super init];
}
- (void) setTime: (int) milliseconds {
    timeLengthInMS = [[NSNumber alloc] initWithInt:milliseconds];
}
- (void) startTimer {
    timer = [NSTimer scheduledTimerWithTimeInterval:([timeLengthInMS longValue]*0.001) invocation:methodInvocationObject repeats:NO];
}
- (void) cancelTimer {
    [timer invalidate];
}
-(void) dealloc {
    [timer release];
    [methodInvocationObject release];
    [timeLengthInMS release];
    [super dealloc];
}

@end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不必了 2024-11-05 09:32:07

这些看起来像是延迟后的一次性触发;您是否考虑过使用类似的东西:

[myObject performSelector:@selector(playEmory) withObject:nil afterDelay:myDelay];

其中 myObject 是带有 playEmory 例程的实例,而 myDelay 是一个 float您希望操作系统在进行调用之前等待的秒数?

您可以找到有关这种 performSelector 的更多信息 此处

These look like one-time firings after a delay; have you considered using something like:

[myObject performSelector:@selector(playEmory) withObject:nil afterDelay:myDelay];

where myObject is the instance with the playEmory routine and myDelay is a float of the seconds you want the OS to wait before making the call?

You can find out more information about this flavor of performSelector here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文