如何在Objective-C中使用带有NSTimer的运行循环

时间:2014-04-30 04:23:33

标签: objective-c nstimer

我正在写一个小程序,每隔几秒就打印到控制台。 目标是每N秒在一个数组中的十个对象中的每一个上调用一个函数,其中n是一个类变量。我想知道如何将这样的定时器循环合并到我的代码中。这就是我所拥有的。我非常感谢你的回应。谢谢。

ALHuman.m

static NSInteger barkInterval = 3;
@implementation ALHuman

-(void)setMyDog:(ALDog *)dog{
    myDog = dog;
}
-(ALDog *)getMyDog{
    return myDog;
}
+(NSInteger)returnBarkInterval {
    return barkInterval;
}
-(void)createDog{
    ALDog *aDog = [[ALDog alloc]init];
    char dogName [40] = " ";
    NSLog(@"Please enter a name for %s's dog",[self name]);
    scanf("%s",dogName);
    [aDog setName:dogName];
    char barkSound [40] = "";
    NSLog(@"Please enter a bark sound for dog: %s",[aDog name]);
    scanf("%s",barkSound);
    [myDog setBarkSound:barkSound];
    [myDog setCanBark:YES];
    [self setMyDog:aDog];
    }
    -(void)callDog:(NSInteger)numberOfResponses {
    NSLog(@"%s",[[self getMyDog] name]);
    [[self getMyDog] bark:numberOfResponses];

    }
    -(NSInteger)getRandomNumberBetween:(NSInteger)from to:(NSInteger)to {

        return (NSInteger)from + arc4random() % (to-from+1);
    }
    -(void)timerFireMethod:(NSTimer *)timer {
    [self callDog:[self getRandomNumberBetween:1 to:5]];
    }
    @end

的main.m

int main(int argc, const char * argv[])
{

@autoreleasepool {

    NSMutableArray *people = [[NSMutableArray alloc]init];
    for (int i = 0; i < 10; i++) { // I didn't want to create a class method for creating these humans and their dogs, because it is unneccessary.
        ALHuman *person = [[ALHuman alloc]init];
       // NameGenerator *name = [[NameGenerator alloc]init]; I need to work on implementing this
        [person setName:"Bob"];
        [person createDog];
        [person setHeight:[person getRandomNumberBetween:5 to:8]];
        [people addObject:person];
    }


    NSLog(@"%@",people);

    NSRunLoop* myRunLoop = [NSRunLoop currentRunLoop]; //Here is where I am having trouble 
    for(ALHuman *human in people){
            [NSTimer timerWithTimeInterval:[ALHuman returnBarkInterval] target:human selector:@selector(timerFireMethod:) userInfo:NULL repeats:YES];
        }

return 0;
}
 }

2 个答案:

答案 0 :(得分:0)

首先,+[NSTimer timerWithTimeInterval:...]创建并返回一个新的计时器对象,但是你忽略了返回值。所以,那些计时器对象只是丢失而且毫无用处。您要么手动将它们安排到运行循环中,要么改为使用+scheduledTimerWithTimeInterval:...

其次,您允许执行流向return语句,该语句退出main()函数。当发生这种情况时,该过程终止。它不会等待任何计时器开火或其他任何事情。

如果你想等待并允许那些计时器触发,你需要手动运行运行循环(因为你不在应用程序的主线程中,这将为你运行运行循环)。您可以调用[myRunLoop run][myRunLoop runUntilDate:someDate],或围绕[myRunLoop runMode:someMode beforeDate:someDate]的调用构建循环。这取决于您希望程序在什么情况下退出,如果有的话。

答案 1 :(得分:0)

使用这个简单的runloop controller class

(未测试):

int main(int argc, const char * argv[])
{
    @autoreleasepool {

        RunLoopController *runLoopController = [RunLoopController new];
        [runLoopController register];

        NSMutableArray *people = [NSMutableArray new];
        NSMutableArray *timers = [NSMutableArray new];
        for (int i = 0; i < 10; i++) {
            ALHuman *person = [[ALHuman alloc]init];
            // NameGenerator *name = [[NameGenerator alloc]init]; I need to work on implementing this
            [person setName:"Bob"];
            [person createDog];
            [person setHeight:[person getRandomNumberBetween:5 to:8]];
            [people addObject:person];
            NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:[ALHuman returnBarkInterval]
                                                              target:person
                                                            selector:@selector(timerFireMethod:)
                                                            userInfo:nil
                                                             repeats:YES];
             [timers addObject:timer];
        }

        NSLog(@"%@",people);

        while ([runLoopController run])
            ;

        [runLoopController deregister];
    }
}

但是,您面临的问题是如何在完成后终止程序。您可以安装信号处理程序,也可以使用其他指标来确定程序已完成,然后调用[[RunLoopController mainRunLoopController] terminate]

RunLoopController使用简单的信令机制(MACH端口)以便知道runloop必须终止。其他用法示例存在于上述链接中的github repo上。