【问题标题】:Achieve method with passed variables in @selector在@selector 中使用传递的变量实现方法
【发布时间】:2026-01-28 15:50:01
【问题描述】:

这里:

distanceTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(applyShot:newPositionOne.x with:newPositionOne.y) userInfo:nil repeats:NO];

^^ 这不起作用。

必须等于这个

[self applyShot:newPositionOne.x with:newPositionOne.y];

在运行这个方法之前我基本上需要延迟,它会传递变量,因为在方法运行时它们会有所不同,所以它必须以某种方式记住它们。

但是,我终其一生都无法弄清楚如何在 @selector 中传递变量。

例如,我以前用 button.tag 做过,但从来没有这样做过。

任何帮助将不胜感激,谢谢。

我知道我可以只设置全局变量,但是可以传递它们吗?

【问题讨论】:

    标签: objective-c


    【解决方案1】:

    好的,您可以做几件事。你是对的,很难将变量传递给@selector() 声明。这里有两个选项:

    1) 调用处理变量的不同方法(在您的类中定义)。例如:

    distanceTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(applyShot) userInfo:nil repeats:NO];
    
    - (void)applyShot
    {
        // manipulate variables and do your logic here
    }
    

    2) 将字典传递给 userInfo 参数:

    scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:

    这本词典可以是这样的:

    NSDictionary *params = @{@"newXPosition: @(90), @""newYPosition: @(100)"};
    

    然后只需更改您的 applyShot: 方法以接收 NSDictionary 参数,然后通过那里的字典解析以找到相关值并“应用镜头”。

    【讨论】:

    • 我真正遇到的问题是它是模拟distance travelled by a bullet 所以他们按下火,一秒钟后你会看到影响。但是,如果他们在击中之前再开一枪,它将渲染最新一枪posX & posY,因此会删除第一枪的预期位置。我认为字典将是我最好的选择,但是,它会解决这个问题吗?
    • 这听起来像是一个新问题。听起来您可能想重新考虑您的设计。拥有一个 posX 和一个 posY 变量真的永远无法满足多个子弹的位置。但是,很难用显示的代码量来判断。我建议针对您刚刚在上面的评论中列出的问题提出一个新问题。
    • 这些位置作为节点添加到射击时保存的位置的背景中,这一直很好,直到我现在将轨迹和速度应用到方程中。然而,幸运的是,调度方法让我能够继续我目前的设计。感谢您的回答并感谢您的解释。
    【解决方案2】:

    选择器不是封装的方法。选择器只是消息的名称。你可以把它想象成一个字符串(它曾经被实现为一个字符串)。

    解决此问题的传统方法是使用 NSInvocation 来打包完整的方法调用,而不仅仅是消息的名称。 Arguments in @selector 很好地涵盖了这一点。处理它的另一种方法是将您的选项打包到userInfo 并更改您的方法以从中读取其参数。

    但现在通常更好的解决方案是改用dispatch_after

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC),
                   dispatch_get_main_queue(),
                   ^(void){
                       [self applyShot:newPositionOne.x with:newPositionOne.y];
                    });
    

    【讨论】:

    • 完美运行,谢谢。这是首选方法,还是我应该选择字典路径?
    • dispatch_after 现在是大多数情况下的首选方法。 NSTimer 是一个强大的工具,但大部分已被 GCD 中的 dispatch_ 函数所取代。