This is an embarrassing question but it involes Xcode and the iPhone SDK.
Why would I need to set more than one timer? And do 2 timers take up more 'tics' than 1 timer or are they all based on the same master internal clock?
Is it better to add 1 timer routine and just have it call all the things I need to make happen or have 5 or 6. I'm not new to programing but I'm completely new to xCode and just trying to wrap my head around it.
Eg. If I have a timer updating the clock on the screen, and I also want to update the GPS position, is there any reason not to have the same timer update both?
Thank you.
One is that timer delegate will operate in separate threads. So in your case, when only one timer is used, if the GPS acquisition takes to much time, your screen will feel unresponsive because the clock will be unregularly updated.
Related
(Swift on Xcode 7.3)
I'm currently working on two independent iPhone apps, both of which use events fired by a repeating NSTimer.
Application A displays an analogue clock with a smooth second hand movement. The timer fires every second and advances all three clock hands appropriately.
Application B displays a weather forecast which is updated every fifteen minutes, after first checking the iPhone's current location.
The question is, is using NSTimer for each of these apps an efficient use of the iphone's resources? If not, what alternatives are available for firing regular events.
(The long term plan is to combine both of these iPhone applications - once they have been refined - into a larger iPad application.)
so i have built my first application in X Code using swift, and i have also taken the time to add the game centre functionality to it, however my question is, how would i delay the start of my game, in order for game centre to load, as of right now, the game starts, and then the game centre banner appears on top of my game before disappearing.
would it be sufficient to use something like, on the function containing my main game attributes:
NSTimer.scheduledTimerWithTimeInterval()
or
would i be better off adding a splash screen?
if anyone has any other suggestions, that would be helpful.
thanks in advance.
Better to subscribe under GameCenter, listen a complete event and then produce your next initialization. Avoid timers in similar situations, because time of processing depends from many factors, and rely to specific delay is not good idea.
If you are waiting for the game to load, then starting a timer is probably not the best solution, because you don't know how long the loading takes on different devices with different capabilities.
A better idea is to load your game and then have a completion method that is called to start the game when it is ready to be run.
I have a timer app, it counts up for an indefinite amount of time (until the user stops the timer). It works much like the default iOS clock stopwatch.
I have read the articles about being a responsible background app. I don't have any UI changes happening and stop the timer when the app goes in the background and resume the timer upon returning to foreground. The app does send a local notification every 30 minutes or so to remind the user to take a break.
Problem: Without fail my app is terminated after a few hours (between 2-6 or so hours) and the current timer and info is lost.
Things I've tried:
-As aforementioned I changed my app to follow the guidelines of being a responsible background app (before I had the timer UI counting up and also the timer running, even while in background). I thought this would solve the problem since my app isn't using up much memory or doing any intensive tasks.
-I also have tried saving out the data of the current timer (to NSUserDefaults) in ApplicationWillTerminate and then restore it on DidFinishLaunchingWithOptions. It doesn't seem to work. It's almost like my app is force quit or something because if ApplicationWillTerminate was being called then it would save the data and restore it upon the app launching again. Mystery.
-Currently I'm saving an NSDate of the start time of the NSTimer on ApplicationDidEnterBackground, invalidating the timer, and starting the timer and restoring the start time upon ApplicationWillEnterForeground. Still no luck.
The thing is this is affecting a very small percentage of my users--so it's not like it's a problem for everyone, which makes it more confusing. I still want to fix it of course because it's a pretty lame bug--and I've encountered it myself (on an iPhone 5), so it's not necessarily an old iPhone low memory somethingorother problem.
This has really boggled me, I've done my research and also scoured fairly well the stack overflow questions and don't seem to find much of anything to help me.
Any help would be appreciated, feel free to ask more questions or tell me to clarify.
applicationWillTerminate is basically never called. It will not be called when your app is in the background and it gets removed from memory. You should expect your app to be removed from memory if it hasn't been used for a while. How long "a while" is depends on what else the device is doing at the time... Best to use applicationDidEnterBackground: or applicationWillResignActive:.
When your app goes into the background, record your timer's elapsed time (eg: in NSUserDefaults or however you prefer). Also record the current time. When the app comes back into the foreground, look at the two values you recorded and update the elapsed time accordingly, ie:
elapsedTime = savedElapsedTime + (currentTime - timeWentIntoBackground)
There's really no reason your app needs to remain active in the background burning the user's battery just to keep track of seconds ticking by.
Also, don't rely on applicationWillTerminate. Use applicationWillEnterBackground.
Making a simple card game, and it it should ok when the user is in control since he will push a button. It will call my method assigned to that button and logic will be performed and screen updated.
But when the players turn ends, and i want the AI to run everything for a few seconds, update the screen with its decisions etc. Handle some logic, call some animation before handing the control back to the user.
Is there a method i can override in my Controller class that which is a subclass of NSObject that gets called every loop or at least 5-10times a second? Or how is it you guys handle this?
Thanks
-Code
It doesn't seem like you want a background thread at all (at least not one you make) or a timer.
What you really want to to is visually animate the AI actions, to that end look at the CoreAnimation stuff, to define animations for AI actions and then play them. You can specify a time period an animation is to take.
Look at this project for examples of animation from the simple to the complex:
http://github.com/neror/CA360
Just create a an NSTimer that calls a tick method at whatever frequency you desire. But keep in mind that NSTimer is not guaranteed to be precise, so in order to avoid gradually accumulating errors, you might want to check how much time has actually passed (e.g. if the timer fires an average of 10 ms late over 500 ticks, code that depends on precise timing will be five seconds off).
I made a game that uses many timers throughout the code. However the timer has to deal with many tasks in such a small amount of time which leads to the problem where there is lag in my game. For example, my timer runs at an interval of (0.05) and it needs to draw and update many of the images on the screen. Is there any way I can distribute the work flow so that the program runs much smoother?
Thanks
Kevin
I would use an NSThread instead of an NSTimer. I have had more success in this area using NSThread because it runs on an independant thread and is not fired off your main ui thread. In the loop for the thread sleep it for 1/20 (your 0.05) of a second. Because the thread is not running on the UI thread all of its tasks should not slow your UI down. However beacsue it is not running on the UI you will have to call performSelectorOnMainThread to get the UI to update from this background thread. I put a lock on my update method (a simple boolean) that says if the last ui update has not happened, just skip this one. then if im running out of processing time i just drop a frame or two here and there. I also do a lot of checking to see if anything has actually changed before i redraw.
Simple solution: Ditch NSTimer.
Move your redrawing code to a single method, then use CADisplayLink. The issue with using your NSTimer approach is that everything is being redrawn too fast or too slow for the screen. By using CADisplayLink, you can synchronize your redraw code to the screen refresh rate. All you need to do then is touch up your code so that it can deal with not being called at a specific time.
And yes, check to make sure you don't need to redraw as Aran Mulholland said above. Just make sure the checks don't take as long as a redraw.
And remember to optimize your code. A lot. Use ivars to access objects, but the whole property (self.myObject =) to set your objects.