iPhone开发人员--性能选择器:withObject:afterDelay还是NSTimer?
要每x秒重复一次方法调用(或消息发送,我想合适的术语是),最好使用NSTimer(NSTimer的scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:)还是让方法在最后递归地调用自己(使用performSelector:withObject:afterDelay)?后者不使用对象,但可能不太清晰/可读?另外,为了让你知道我在做什么,这只是一个带有标签的视图,它倒计时到午夜12:00,当它达到0时,它将闪烁时间(00:00:00),并永远播放蜂鸣音 谢谢 编辑:还有,重复播放SystemSoundID(永远)的最佳方式是什么? 编辑:我最终用这个来永远播放SystemSoundID:iPhone开发人员--性能选择器:withObject:afterDelay还是NSTimer?,iphone,nstimer,tail-recursion,repeat,Iphone,Nstimer,Tail Recursion,Repeat,要每x秒重复一次方法调用(或消息发送,我想合适的术语是),最好使用NSTimer(NSTimer的scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:)还是让方法在最后递归地调用自己(使用performSelector:withObject:afterDelay)?后者不使用对象,但可能不太清晰/可读?另外,为了让你知道我在做什么,这只是一个带有标签的视图,它倒计时到午夜12:00,当它达到0时,它将闪烁时间(00:00
// Utilities.h
#import <Foundation/Foundation.h>
#import <AudioToolbox/AudioServices.h>
static void soundCompleted(SystemSoundID soundID, void *myself);
@interface Utilities : NSObject {
}
+ (SystemSoundID)createSystemSoundIDFromFile:(NSString *)fileName ofType:(NSString *)type;
+ (void)playAndRepeatSystemSoundID:(SystemSoundID)soundID;
+ (void)stopPlayingAndDisposeSystemSoundID;
@end
// Utilities.m
#import "Utilities.h"
static BOOL play;
static void soundCompleted(SystemSoundID soundID, void *interval) {
if(play) {
[NSThread sleepForTimeInterval:(NSTimeInterval)interval];
AudioServicesPlaySystemSound(soundID);
} else {
AudioServicesRemoveSystemSoundCompletion(soundID);
AudioServicesDisposeSystemSoundID(soundID);
}
}
@implementation Utilities
+ (SystemSoundID)createSystemSoundIDFromFile:(NSString *)fileName ofType:(NSString *)type {
NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:type];
SystemSoundID soundID;
NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
return soundID;
}
+ (void)playAndRepeatSystemSoundID:(SystemSoundID)soundID interval:(NSTimeInterval)interval {
play = YES
AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL,
soundCompleted, (void *)interval);
AudioServicesPlaySystemSound(soundID);
}
+ (void)stopPlayingAndDisposeSystemSoundID {
play = NO
}
@end
//Utilities.h
#进口
#进口
静态void soundCompleted(SystemSoundID soundID,void*我自己);
@接口实用程序:NSObject{
}
+(SystemSoundID)createSystemSoundIDFromFile:(NSString*)类型的文件名:(NSString*)类型;
+(无效)播放和重复系统声音ID:(系统声音ID)声音ID;
+(无效)停止铺设和处置系统;
@结束
//公用事业
#导入“Utilities.h”
静态布尔播放;
静态void soundCompleted(SystemSoundID soundID,void*间隔){
如果(玩){
[NSThread sleepForTimeInterval:(NSTimeInterval)interval];
AudioServicesPlaySystemSound(soundID);
}否则{
AudioServicesRemoveSystemSoundCompletion(声音ID);
AudioServicesDisposeSystemSoundID(soundID);
}
}
@实现实用程序
+(SystemSoundID)createSystemSoundIDFromFile:(NSString*)类型的文件名:(NSString*)类型{
NSString*path=[[NSBundle mainBundle]pathForResource:type的文件名:type];
系统声音ID;
NSURL*filePath=[NSURL fileURLWithPath:path isDirectory:NO];
AudioServicesCreateSystemSoundID((CFURLRef)文件路径和soundID);
返回声音ID;
}
+(void)播放和重复系统声音ID:(SystemSoundID)声音ID间隔:(NSTimeInterval)间隔{
播放=是
AudioServicesAddSystemSoundCompletion(声音ID,NULL,NULL,
声音完成,(void*)间隔;
AudioServicesPlaySystemSound(soundID);
}
+(无效)停止铺设和处理SystemsSoundID{
播放=否
}
@结束
好像很好用。。对于标签闪烁,我想我将使用NSTimer。计时器更适合于严格定义的间隔。如果函数调用本身有延迟,则会失去准确性,因为它没有真正同步到时间间隔。总有运行实际方法本身所花费的时间,这会使间隔延长
我要说的是,请坚持使用NSTimer。因为您的应用程序取决于时间准确性(即它需要每秒执行一次),所以NSTimer会更好。方法本身的执行需要一些时间,NSTimer也可以(只要你的方法不超过1秒,如果每秒调用一次的话) 要重复播放声音,可以设置完成回调并在此处重放声音:
SystemSoundID tickingSound;
...
AudioServicesAddSystemSoundCompletion(tickingSound, NULL, NULL, completionCallback, (void*) self);
...
static void completionCallback(SystemSoundID mySSID, void* myself) {
NSLog(@"completionCallback");
// You can use this when/if you want to remove the completion callback
//AudioServicesRemoveSystemSoundCompletion(mySSID);
// myself is the object that called set the callback, because we set it up that way above
// Cast it to whatever object that is (e.g. MyViewController, in this case)
[(MyViewController *)myself playSound:mySSID];
}
在其他答案的基础上再补充一点,递归调用的情况是,调用可能需要未知的时间量——比如说,使用少量数据重复调用web服务,直到完成为止。每次调用可能需要一些未知的时间,因此在web调用返回之前,您让代码什么也不做,然后发送下一批,直到没有更多的数据需要发送,代码不会再次调用自己。这有助于对比这两种方法。