Objective c 从NSTimer选择器访问实例变量

Objective c 从NSTimer选择器访问实例变量,objective-c,Objective C,第一个新手问题:选择器和方法之间有什么区别 第二个新手问题(谁会想到):我需要基于实例变量循环一些代码,并在循环之间暂停,直到满足某些条件(当然是基于实例变量)。我研究了睡眠,我研究了NSThread。在这两次讨论中,许多人问我为什么不使用NSTimer,所以我在这里 好的,所以让一个方法(选择器?)在一个时间表上启动就足够简单了。我的问题是,我不知道如何从NSTimer激发的代码中查看在计时器外部设置的实例变量。我需要从NSTimer选择器代码中查看这些变量,因为我1)将更新它们的值,2)将根

第一个新手问题:选择器和方法之间有什么区别

第二个新手问题(谁会想到):我需要基于实例变量循环一些代码,并在循环之间暂停,直到满足某些条件(当然是基于实例变量)。我研究了睡眠,我研究了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
}

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

[NSTimer scheduledTimerWithTimeInterval:1.0 target:aMyClassInstance selector:@selector(doStuff) userInfo:nil repeats:YES];
实例(您称之为
amyclasinstance
)将是
self


或者,您可以将
amyclasinstance
和任何其他对象放入
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];
-(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
}
然后,在
doStuff:
选择器中,您可以按如下方式将它们取出:

NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
                          aMyClassInstance, @"a",
                          bMyClassInstance, @"b",
                          cMyClassInstance, @"c",
                          nil];
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(doStuff:) userInfo:userInfo repeats:YES];
-(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
}

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

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参数。

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


选择器从对象中“选择”要使用的方法。假设你有一些动物类,比如
,和
,它们都是
动物
的子类。它们都实现了一个名为
makeSound
的方法。每个类都有自己的
makeSound
实现,否则所有动物的声音都一样。所以,所有动物都有不同的发声方法,但你可以让每只动物使用相同的选择器发声。换句话说,您正在选择动物的
makeSound
方法。

有趣。。。有没有办法访问多个对象的实例变量?例如,如果我在aMyClassInstance、bMyClassInstance、cMyClassInstance、someOtherClassInstance等中有一些变量会影响定时事件的结果,那么您只需要在某个地方保留指向它们的指针。您可以将它们设置为目标的所有IVAR,也可以将它们全部放入作为
userInfo
参数传递的
NSDictionary
。您将无法直接访问所有对象的实例变量,但您可以访问对象的公共接口,该接口可用于实现相同的目的。感谢您提供的信息,我现在正在尝试完成NSDictionary的详细信息。您能否举例说明我将如何使用NSDictionary在NSDictionary中存储指向aMyClassInstance的指针,以及如何从NSTimer调用的方法引用该字典?是否有方法访问多个实例的实例变量?是的。只需将它们包装到NSDictionary中,将字典作为userInfo传递并随意检索它们。我是将想要的变量包装到NSDictionary中,还是将指向整个amyclasInstance对象的指针放在其中?无论哪种方式,当我通过NSDictionary从NSTimer调用的方法设置变量时,它会设置实际的实例变量吗?类似于NSMutableDictionary*myDictionary=[NSMutableDictionary new];[myDictionary setObject:aMyClassInstance forKey:@“aMyClassInstance”];是的,这就是我的意思(将实例指针放入字典)。由于amyclasinstance是指向MyClass实例的指针,如果您将其放入字典并稍后检索,则将修改同一实例。如果您想确定,只需在代码中放置一个断点即可将其签出。