
Note: This post is more or less a discovery of common sense solutions. When I realized the best, and conveniently the least complicated, solution it was only then I saw how far off the deep end my mind went.
The frequency of skill points updating can easily be calculated and the value can accurately be guessed. A running counter of the current skill points for an app of this nature would almost be a necessity.
Here's the simple reason why there is a problem: NSTimers just aren't reliable. From Apple's own class reference of NSTimers: "If the firing time is delayed so far that it passes one or more of the scheduled firing times, the timer is fired only once for that time period; the timer is then rescheduled, after firing, for the next scheduled firing time in the future."
So say the counter is running on the main thread and is updating the current NSManagedObject being learned. If you press a menu item and hold it long enough, it could easily cause your skill points counter to be thrown off.
One might then suggest why not do the updating on a separate thread? That would certainly solve the issue of not having user or other events interfere. But now you're creating a whole slew of new problems. First off, I have to have a perpetual secondary thread for the shear purpose of keeping a counter. This means doing quite a bit of learning on maintaining an active run loop. Then there's the problems of sending messages to the new thread. Ok, so even if I somehow manage to solve all those problems, there's still remains another unsolved one: Context locking. Currently, I have two contexts; one for displaying data and one for updating. That was tricky enough to figure out. If, for whatever reason, either of them get locked long enough, I'm back to the same problem. Adding a third one just for the sake of updating one object on a timer is just plain silly.
Then I thought of a 3rd idea. Why not a 3rd thread! The main one for user interaction; A second one for updating values; Then the third to have a timer that only updates a variable. The second one would query the third one for the proper value. If, for whatever reason, the second thread pauses too long, the counter will still continue. Brilliant!
And then it dawned on me. Why am I using an NSTimer for keeping the accuracy of the skill point values? And why does something so simple have to have multiple threads? The real solution is just create a static date to reference for computing the amount of skill points. Have a timer be set up on the main thread to call an update method. This method takes the date, computes the skill points the character would have based on that date and updates the object. If somehow the timer doesn't fire one or more times consecutively, the next time it does it will update to the appropriate values.

No comments:
Post a Comment