【问题标题】:Is NSTimer auto retained?NSTimer 是否自动保留?
【发布时间】:2026-01-30 10:45:01
【问题描述】:

我有一个 -(void)save 方法,当用户单击导航栏按钮时会调用该方法。在该方法中是以下 NSTimer:

[NSTimer scheduledTimerWithTimeInterval:.25f target:self selector:@selector(flashBackgroundRed) userInfo: nil repeats: flashRepeat];

计时器重复 4 次,因为 flashBackgroundRed 保持计数并在 4 次点击后将 flashRepeat 设置为 NO。用户第一次点击保存时一切正常。但是,如果用户一直使用不正确的数据点击保存,我会将它们保留在当前视图中。出于某种原因,闪光灯增加得更快。好像每个都是前一个间隔的 25%。我不保留这个计时器。它只存在于 save 方法中。

如果用户点击取消按钮,viewB(一个带有 NSTimer 的)被弹出并显示 viewA。从 viewA 回到 viewB 似乎重置了计时器间隔。但越来越快的闪烁周期又开始了。有什么想法吗?

【问题讨论】:

    标签: objective-c iphone cocoa-touch


    【解决方案1】:

    NSTimer 只要被调度,就会被运行循环保留。

    听起来问题在于您不断在稍微不同的时间创建等效的重复计时器,因此它们在视觉上以与您想要的频率不同的频率结合在一起形成一种效果。尝试存储对计时器的引用,并在您要创建新计时器时将其无效。

    【讨论】:

    • 是的 - 在运行上述代码之前,我已经声明了一个类级别的引用并使其无效。工作正常。
    【解决方案2】:

    听起来您安排的计时器比您打算的要多。

    一旦安排好,计时器就会一直保留到失效为止。重复计时器必须手动失效。

    repeats 参数指定计时器是否重复。您无法指定计时器应重复多少次,只能指定是否重复。

    另外,您的选择器的方法签名是错误的。它应该看起来像

    -(void)timerFireMethod:(NSTimer*)theTimer
    

    在您的计时器回调中,您可以确定是否希望计时器继续重复;如果没有,请调用 [timer invalidate]。

    【讨论】:

    • 如何在选择器中使用参数?
    • 看起来像 [NSTimer scheduledTimerWithTimeInterval:.25f target:self 选择器:@selector(flashBackgroundRed:) userInfo: nil repeats: flashRepeat];
    • 为什么不这样:selector:@selector(flashBackground::[UIColor redColor]) ...for... -(void) flashBackground:(NSTimer*) theTimer attentionColor:( UIColor*)theColor{...}
    • userInfo 接受任何对象,这就是选择器参数所在的位置。例如,如果我需要多个参数,我会将一个数组传递给 userInfo,并在我的选择器目标中将其作为 (NSMutableArray *)[theTimer userInfo] 取出。
    • 我认为你对这个选择器的工作方式有点困惑。创建计时器时传递的选择器是一个回调,在计时器触发时调用。触发的计时器是传递给选择器的参数,正如您所说,您可以在该计时器的用户信息中存储您需要的任何内容。