objective c - safety of using cocoa's performSelectorOnMainThread thousands of times -
in app have worker thread sits around doing lot of processing. while it's processing, sends updates main thread uses information update gui elements. done performselectoronmainthread. simplicity in code, there no restrictions on these updates , sent @ high rate (hundreds or thousands per second), , waituntildone false. methods called take variable , copy private member of view controller. of them update gui directly (because i'm lazy!). once every few seconds, worker thread calls performselectoronmainthread waituntildone set true (this related saving output of current calculation batch).
my question: safe use of performselectoronmainthread? ask because encountered problem displayed values stopped updating, despite background thread continuing work without issues (and produce correct output). since fed values way, wondered if might have hit limit in number of messages. checked usual suspects (overflows, leaks, etc) , everything's clean. haven't been able reproduce problem, however.
for simplicity in code, there no restrictions on these updates , sent @ high rate (hundreds or thousands per second), , waituntildone false.
yeah. don't that. not sake of laziness in internal application.
it can cause kinds of potential problems beyond making main run loop unresponsive.
foremost, starve worker thread cpu cycles main thread spinning trying update ui rapidly messages arrive. given drawing oft done in secondary thread, cause yet more thread contention, slowing things down more.
secondly, messages consume resources. potentially lots of them , potentially ones relatively scarce, depending on implementation details.
while there shouldn't limit, there may practical limit that, when exceeded, things stop working. if case, bug in system, 1 unlikely fixed beyond console log says "too many messages, fast, make fewer.".
it may bug in code, though. transfer of state between threads area rife pitfalls. sure cross-thread-communication code bullet proof? (and, if bulletproof, quite huge performance cost thousands/sec update notifications).
it isn't hard throttle updates. while commented suggestions reasonable, can done more (nsnotificationqueue fantastic, overkill unless updating main thread many different places in computation).
- create nsdate whenever notify main thread , store date in ivar
- next time go notify main thread, check if more n seconds have passed
- if have, update ivar
- [bonus performance] if date comparison expensive, consider revisiting algorithm move "update now" trigger somewhere less frequent. barring that, create int ivar counter , check date every n iterations
Comments
Post a Comment