NSTimer无效后,后台线程NSRunloop运行不会退出!为什么?

问题描述

| 我正在创建一个NSTimer并将其添加后台线程的运行循环中。 我的代码类似于此答案的后台线程示例:iPhone-SDK:在后台调用函数? 创建计时器并将其从gdb附加到runloop后,我I0ѭ并输出以下内容
<CFRunLoop 0x695b090 [0x16a62c0]>{wakeup port = 0x6907,stopped = false,current mode = kcfRunLoopDefaultMode,common modes = <CFBasicHash 0x6936e60 [0x16a62c0]>{type = mutable set,count = 1,entries =>
    1 : <CFString 0x16abba8 [0x16a62c0]>{contents = \"kcfRunLoopDefaultMode\"}
},common mode items = <CFBasicHash 0x695e160 [0x16a62c0]>{type = mutable set,entries =>
    0 : <CFRunLoopTimer 0x69398a0 [0x16a62c0]>{valid = Yes,interval = 6,next fire date = 329774303,callout = __NSFireTimer (0x212399),context = <CFRunLoopTimer context 0x6903a10>}
},modes = <CFBasicHash 0x6904120 [0x16a62c0]>{type = mutable set,entries =>
    1 : <CFRunLoopMode 0x6946180 [0x16a62c0]>{name = kcfRunLoopDefaultMode,port set = 0x6807,timer port = 0x6b03,sources0 = (null),sources1 = (null),observers = (null),timers = <CFArray 0x695e180 [0x16a62c0]>{type = mutable-small,values = (
    0 : <CFRunLoopTimer 0x69398a0 [0x16a62c0]>{valid = Yes,context = <CFRunLoopTimer context 0x6903a10>}
)}
},}
}
这表明1个计时器已附加到运行循环 稍后在使计时器无效之后,NSRunloop运行方法不会退出,但是在我暂停调试器并从gdb中再次弹出“ 0”后,它看起来像这样:
<CFRunLoop 0x695b090 [0x16a62c0]>{wakeup port = 0x6907,count = 0,entries =>
},values = ()}
},}
}
现在\“ timers \”条目具有0个对象。但是线程继续运行。我经常离开屏幕然后返回,这样会导致后台线程的建立,最终这些线程将在使用过多资源后终止应用程序。计时器无效后不会触发,但仍保留后台线程。 我知道我可以将计时器移回主线程或使用NSThread sleepForTimeInterval创建我自己的简单计时器线程,但是我想保留主线程以进行GUI更新,并在可能的情况下使用NSTimer。     

解决方法

        从
-[NSRunLoop run]
文档:   从运行循环中手动删除所有已知的输入源和计时器并不能保证运行循环将退出。 您应该使用另一种方法,可能在循环中使用“ 5”,同时使计时器无效,并设置一个标志,指示运行循环应结束。     ,        这对我来说停止了运行循环:
[[NSRunLoop currentRunLoop] runUntilDate: [NSDate date]];
如果您正在编写可能在主线程上运行(并因此使用主运行循环)的代码,则应在执行此操作之前检查看看当前运行循环是否是主运行循环-否则,您将轰炸您的应用程序。
// Kill the runloop now.
NSRunLoop* rl = [NSRunLoop currentRunLoop]; // Get the runloop
if (rl != [NSRunLoop mainRunLoop])
{
    // Set it running again,but only until now. 
    // In other words,STOP!!!
    [rl runUntilDate: [NSDate date]];
}
    ,        我需要阅读[NSTimer invalidate]的文档。...必须从与安装计时器相同的线程中调用此方法。如果不从同一线程调用它,则计时器线程将不会退出。     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...