在 iOS 上使用多个 NSTimer - 仅触发一个计时器
需要帮助解决问题。
目标
我正在编写一个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这些看起来像是延迟后的一次性触发;您是否考虑过使用类似的东西:
其中
myObject
是带有playEmory
例程的实例,而myDelay
是一个float
您希望操作系统在进行调用之前等待的秒数?您可以找到有关这种
performSelector
的更多信息 此处。These look like one-time firings after a delay; have you considered using something like:
where
myObject
is the instance with theplayEmory
routine andmyDelay
is afloat
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.