从NSTimer选择器访问实例变量

时间:2010-06-03 07:55:13

标签: objective-c

首先是新手问题:选择器和方法有什么区别?

其次新手问题(谁会想到):我需要基于实例变量循环一些代码并在循环之间暂停,直到满足一些条件(当然基于实例变量)。我看着睡觉,我看着NSThread。在通过这些选项进行的两次讨论中,很多人问我为什么不使用NSTimer,所以我在这里。

好的,这样就足以让一个方法(选择器?)按计划启动。我遇到的问题是我不知道如何在代码NSTimer触发时看到我在计时器外设置的实例变量。我需要从NSTimer选择器代码中看到这些变量,因为我1)将更新它们的值,2)将根据这些值设置标签。

这里有一些代码显示了这个概念......最终我也基于myVariable使定时器无效,但是为了代码清晰,我排除了它。

MyClass *aMyClassInstance = [MyClass new]; 
[aMyClassInstance setMyVariable:0];
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(doStuff) userInfo:nil repeats:YES];
[NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(doSomeOtherStuff) userInfo:nil repeats:YES];

- (void) doStuff {
        [aMyClassInstance setMyVariable:11]; //  don't actually have access to set aMyClassInstance.myVariable
        [self updateSomeUILabel:[NSNumber numberWithInt:aMyClassInstance.myVariable]];  // don't actually have access to aMyClassInstance.myVariable
}

- (void) doSomeOtherStuff {
        [aMyClassInstance setMyVariable:22]; //  don't actually have access to set aMyClassInstance.myVariable
        [self updateSomeUILabel:[NSNumber numberWithInt:aMyClassInstance.myVariable]];  // don't actually have access to aMyClassInstance.myVariable
}

- (void) updateSomeUILabel:(NSNumber *)arg{
        int value = [arg intValue];
         someUILabel.text = [NSString stringWithFormat:@"myVariable = %d", value];  // Updates the UI with new instance variable values
}

3 个答案:

答案 0 :(得分:7)

您可以使用userInfo参数传输任意对象。在这种情况下,您将aMyClassInstance作为userInfo传递:

MyClass *aMyClassInstance = [MyClass new]; 
[aMyClassInstance setMyVariable:0];
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(doStuff) userInfo:aMyClassInstance repeats:YES];

在计时器回调(必须带参数)中,你从计时器中取回userInfo并投下它:

- (void) doStuff:(NSTimer *)timer {
    MyClass *instance = (MyClass *)[timer userInfo];
    [instance setMyVariable:11];
    [self updateSomeUILabel:[NSNumber numberWithInt:instance.myVariable]];
}

巧妙的是,计时器保留了userInfo参数。

答案 1 :(得分:1)

你的一个问题是询问选择器和方法之间的区别。

选择器“选择”要从对象使用的方法。想象一下,您有一些动物类,比如DogCatBirdAnimal的所有子类。它们都实现了一个名为makeSound的方法。每个类都有自己的makeSound实现,否则所有的动物听起来都一样。因此,所有动物都有不同的方法用于发出声音,但您可以使用相同的选择器让每只动物发出声音。换句话说,您正在选择动物的makeSound方法。

答案 2 :(得分:0)

如果您将实例设置为计时器的目标,则可以访问实例变量,如下所示:

[NSTimer scheduledTimerWithTimeInterval:1.0 target:aMyClassInstance selector:@selector(doStuff) userInfo:nil repeats:YES];

该实例(您称之为aMyClassInstance)将为self


或者,您可以将aMyClassInstance和任何其他对象放在userInfo字典中。你会这样做:

NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
                          aMyClassInstance, @"a",
                          bMyClassInstance, @"b",
                          cMyClassInstance, @"c",
                          nil];
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(doStuff:) userInfo:userInfo repeats:YES];

然后,在doStuff:选择器中,您可以将其退回:

-(void) doStuff:(NSTimer*)timer;
{
    MyClass* aMyClassInstance = [[timer userInfo] objectForKey:@"a"];
    MyClass* bMyClassInstance = [[timer userInfo] objectForKey:@"b"];
    MyClass* cMyClassInstance = [[timer userInfo] objectForKey:@"c"];

    //do whatever you want here
}