iOS5 ARC可以安全地从后台选择器安排NSTimers吗? [英] iOS5 ARC is it safe to schedule NSTimers from background selectors?

查看:135
本文介绍了iOS5 ARC可以安全地从后台选择器安排NSTimers吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试调试我的应用程序。

I'm trying to debug my application.

我一直在我的非弧代码中使用一些NSTimer实例(来自主线程):

I've been using some NSTimer instances in my non-arc code like this (from the main thread):

[NSTimer scheduledTimerWithTimeInterval:5 target:musicPlayer selector:@selector(playPause:) userInfo:nil repeats:NO];

如果我将此代码分配给按钮并单击按钮,则此工作正常。计时器开火。

This works fine if I assign this code to a button and click a button. The timer fires.

我也试过:

 if( self.deliveryTimer == nil)
  {                 
self.deliveryTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(playPause:) userInfo:nil repeats:NO];
    }

    -(void)playPause:(NSTimer*)timer
    {
           [deliveryTimer invalidate];
            deliveryTimer = nil;
//more code here

    }

我希望要执行的计时器,按下面的播放/暂停方法,然后转到nil,这样我可以稍后重置计时器。我检查nil的原因是因为我有3个不同的代码路径可以设置定时器。每个都有一个NSLog语句,表明计时器已被安排。

I would expect the timer to execute, hit the play/pause method below, then turn to nil, so I can reset the timer later. The reason why I'm checking for nil is because I have 3 different code paths that may set the timer. Each one has an NSLog statement indicating that the timer has been scheduled.

我的代码运行,我看到计时器正在安排,但它们似乎没有在正常的应用程序执行过程中触发。我正在调查原因。短期计时器,使用相同的逻辑火。当我让应用程序运行一段时间时,我遇到了问题。

My code runs, and I see that the timers are being scheduled, but they don't seem to fire in the course of normal app execution. I'm investigating why. Short term timers, using the same logic fire fine. It is when I let the app run for a while that I'm running into issues.

ARC可以回收NSTimers吗?

我是否重要从performSelectorInBackground设置计时器?当我写这个问题时,我注意到我的一些计时器是通过一个被调用的代码路径创建的:

Does it matter if I set the timer from a performSelectorInBackground? As I was writing up this question, I noticed that some of my timers were created from a code path that is being called through:

[self performSelectorInBackground:@selector(notifyDelegateOfDataPoint:) withObject:data];

后台选择器可能是我的计时器之前没有开火/收回的原因吗?

could the background selector be the reason why my timers do not fire/get reclaimed earlier?

任何帮助都表示赞赏,这个错误已经超过2周了!

Any help is appreciated, this bug has been bugging me for over 2 weeks!

更新:更改后使用主线程的代码用于NSTimers,计时器正确触发,导致音乐播放:

Update: after changing the code to use the main thread for NSTimers, the timers fire correctly, causing the music to play:

   [self performSelectorOnMainThread:@selector(deliverReminder:) withObject:nil waitUntilDone:NO];


-(void)deliverReminder:(id)sender{
     [ NSTimer scheduledTimerWithTimeInterval:10 target:reminderDeliverySystem selector:@selector(playAfterDelay:) userInfo:nil repeats:NO];
    [self postMessageWithTitle:nil message:@"Deliver Reminder Called" action:kNoContextAction];
}

-(void)playAfterDelay:(id)sender
{
    int reminderDelay = reminder.delayValue.intValue;

    [playTimers addObject:[NSTimer scheduledTimerWithTimeInterval:reminderDelay target:self selector:@selector(appMusicPlayerPlay:) userInfo:nil repeats:NO]];


}

这里有一大堆定时器,这是因为我不知道如何使用选择器将原语传递给目标。

Here I have a whole bunch of timers, which is because I don't know how to pass a primitive to a target with a selector.

推荐答案

NSTimer需要在后台线程中运行一个运行循环才能继续触发。主线程已经有一个活动的运行循环,这就是为什么你的计时器在它上面执行时工作正常。

An NSTimer requires a run loop to be running in that background thread for it to keep firing. The main thread already has an active run loop, which is why your timers work fine when executed on it.

如果你想在后台线程中使用你的计时器,你可以执行以下操作:

If you want to use your timers within a background thread, you can do something like the following:

NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
self.deliveryTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(playPause:) userInfo:nil repeats:NO];
[runLoop run];

您的短期计时器开火可能发生了什么,但更长的计时器没有,是他们是在线程仍然处于活动状态时触发,但是没有运行循环以保持运行,在线程到达执行结束后失败。

What was probably happening with your short duration timers firing, but the longer ones not, was that they were firing while the thread was still active, but without a run loop to keep it going, were failing after the thread reached the end of its execution.

我不相信这与ARC有关,虽然你可能需要注意一些东西,因为NSRunLoop会保留一个连接到它的计时器。遵循NSTimers的标准程序应避免ARC问题。

I don't believe this is ARC-related, although there may be something there you'll have to watch for, because the NSRunLoop holds on to a timer that is attached to it. Following standard procedure with NSTimers should avoid ARC problems.

这篇关于iOS5 ARC可以安全地从后台选择器安排NSTimers吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆