Quantcast
Viewing all articles
Browse latest Browse all 4

Background thread NSRunloop run does not exit after NSTimer is invalidated! Why?

I'm creating an NSTimer and adding it to the runloop of a background thread.My code is like the background thread example for this answer: iPhone-SDK:Call a function in the background?

After creating the timer and attching it to the runloop from gdb I po runLoop and it outputs this:

<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, count = 1,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, count = 1,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, count = 1, values = (    0 : <CFRunLoopTimer 0x69398a0 [0x16a62c0]>{valid = Yes, interval = 6, next fire date = 329774303, callout = __NSFireTimer (0x212399), context = <CFRunLoopTimer context 0x6903a10>})}},}}

This shows that 1 timer is attached to the runloopLater after I invalidate the timer the NSRunloop run method doesn't exit but after I pause the debugger and from gdb I po runLoop again it looks like this:

<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, count = 0,entries =>},modes = <CFBasicHash 0x6904120 [0x16a62c0]>{type = mutable set, count = 1,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, count = 0, values = ()}},}}

Now the "timers" entry has 0 objects. But the thread continues to run. I often leave the screen then come back so this leads to a build up of background threads which will eventually kill the app after too many resources are used. The timers don't fire after they are invalidated but the background thread remains.

I know I can move timers back to the main thread or create my own simple timer thread with NSThread sleepForTimeInterval but I would like to keep the main thread for GUI updates and use NSTimer if possible.


Viewing all articles
Browse latest Browse all 4

Trending Articles