iPhone开发 - performSelector:withObject:afterDelay或

2019-08-17 00:01发布

要重复一个方法调用(或消息发送,我想适当的任期)每x秒,是它更好地使用一个NSTimer(的NSTimer的scheduledTimerWithTimeInterval:目标:选择:用户信息:重复:)或有方法递归调用自身在端部(使用performSelector:withObject:afterDelay)? 后者不使用对象,但也许它的不清晰/可读性? 此外,只给你的我在做什么,与倒计时至午夜12时,并且当它到达0,它会闪烁的时间标签它只是一个视图的想法(00:00:00)永远播放提示音。

谢谢。

编辑:也,这将是反复播放一个SystemSoundID(永远)的最佳方法是什么? 编辑:我结束了使用可以永远这样继续玩SystemSoundID:

// 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

似乎很好地工作。而对于标签闪烁,我将使用一个NSTimer我猜。

Answer 1:

计时器是更适合于严格定义的时间间隔。 如果你有你的函数调用本身有延迟,因为它不是一个真正同步到一个时间间隔,你会失去准确性。 总有运行实际方法本身以及其提出的间隔从所花费的时间。

有一个NSTimer坚持,我会说。



Answer 2:

只是有点添加到其他的答案,该情况下递归调用是当呼叫可能需要的时间未知量 - 说你是用少量的数据重复调用Web服务,直到完成。 所以你的代码做什么,直到网络调用返回,则下一批被发送出去,直到没有更多的数据还有待发送的代码不会再次调用自身的每次调用可能需要一些时间未知量。



Answer 3:

由于您的应用程序依赖于时间精度(即它需要每秒执行一次),在的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];
}


文章来源: iPhone dev — performSelector:withObject:afterDelay or NSTimer?