I was wondering if anyone knows of a class in objective-C that stops/delays the application at a specified amount of time during runtime? I've already looked at the Time Manager and NSTimer and don't see how I could possibly put a delay in there. I've never used these two classes before though, so maybe someone else has and could give me a tip? Thanks!
It really depends what you mean by "stops/delays the app." If you have a single threaded app you can just use anyone of the various sleep calls (usleep, sleep, nanosleep, etc). That is probably not what you want though, because it will just result in a hung UI for the user, and won't stop any background threads.
To actually give a decent answer it is probably necessary to know what you are actually trying to do. Are you waiting for something, polling a resource, etc?
#include <unistd.h>
sleep(3); // or usleep(3000000);
I think you're looking for [NSThread sleepForTimeInterval:] That should do the trick. You should also consider using a timer to invoke another function after a delay, because that solution is non-blocking. The NSThread approach will totally lock your application for the time interval if you call it from the main thread.
Related
I've got a MacOS/X app which in general is not averse to app-napping, but sometimes it will spawn one or more child threads to do timing-sensitive networking tasks, which do need to avoid being app-napped.
The elegant thing to do would be to have each of these threads call [[NSProcess processInfo] beginActivityWithOptions [...]] when it starts, and also call [[NSProcess processInfo] endActivity [...]] just before it exits, which would (hopefully) have the effect of avoiding app-nap on my process (or at least on those particular threads) only when one or more of these network-threads is running.
My question is, is this a legal/acceptable calling pattern, or is NSProcessInfo more of a per-process-only kind of API that doesn't implement the thread-safe reference-counting logic that would be necessary to reliably yield the expected behavior if I call it from multiple threads? (if it's the latter, I can implement that logic myself, but I'd rather not reinvent the wheel here)
This API is considered like process-wide, to report that your entire Application is doing the specific kind of job, which should be or should not be affected by power saving heuristics (which are, again, per-process, not per-thread).
The best way to use it would be to begin one activity before all your background threads started, and finish it after all your important background threads finished.
You can do it with DispatchGroup or any other instrument you wish.
That is not the only way though.
beginActivityWithOptions would return the _NSActivityAssertion, which is not generally aware of threads. You could bring your own thread sync mechanism to this party.
Calling this API several times would create several _NSActivityAssertion objects, which is definetely redundant but should work, if you will properly end each of them.
First of all this API should be or should not be affected by power-saving heuristics.
The best way to use it would be to use it with a dispatch group
I have an iOS application using NSThreads for concurrency tasks. I will try to migrate it to be using the Grand Central Dispatch (GCD) for handling concurrency.
The problem is that the app needs information regarding how many threads has been created since a given time. And how many threads that was spawned since that given time is currently running.
At the moment this is done by creating a category that does a method swizzling on the -main method in NSThread. In the new swizzled method it simply increments the total number of threads running and then decrement the same variable before the new swizzled -main method returns.
The problem is that when I use GCD dispatch_async it does not create a NSThread, hence my category approach does not work. How can I achieve the same while using GCD to handle concurrency?
What I would like to detect is when a new block is added to GCD, and when that block has been executed.
Any suggestions on how to achieve the same is very welcome.
EDIT
Many thanks to #ipmcc and #RyanR for helping me out on this. :) I believe I need to tell some more about the background and what I am trying to accomplish.
What I am actually trying is to extend the iOS testing framework Frank. Frank embeds a small web-server within a given app which enables sending HTTP request to the iOS application and thereby simulating events, a swipe or a tap gesture as an example.
I would like to extend it in a way that enables it to wait until all work triggered by a specific simulated event has ended before returning upon a request.
However I found it hard to detect exactly what work was triggered by the received event. And thats how I came to the solution to just reset a thread counter and then increment this counter for all created threads after the event was simulated, and decrement it when the threads are finishing. And then block until threads count became zero again. I know this approach is not perfect either, and it wont work with GCP.
Is there any other way to achieve it? Another possible solution which I have thought of is to specify that everything must run synchronized except the thread handling the HTTP request. However I don't know if this possible.
Any suggestions on how to achieve blocking after each simulated event until work triggered by that event has completed?
The problem is that the app needs information regarding how many
threads has been created since a given time. And how many threads that
was spawned since that given time is currently running.
You will not be able to get this information from GCD. One of the points of GCD is that you do not manage the thread pool. It is opaque. You'll note that even pthreads, the underlying threading library on which NSThread and GCD are built, does not have a (public) means to enumerate all existing threads or get the number of running threads. This is not going to be doable without hard core low level hackery. If you need to control or know the number of threads, then you need to be the one to spawn and manage them, and GCD is the wrong abstraction for you.
At the moment this is done by creating a category that does a method
swizzling on the -main method in NSThread. In the new swizzled method
it simply increments the total number of threads running and then
decrement the same variable before the new swizzled -main method
returns.
Note that this only tells you the number of threads started using NSThread. As mentioned, NSThread is a fairly high level abstraction on top of pthreads. There is nothing to prevent library code from spawning its own threads using the pthreads API that will be invisible to your count.
The problem is that when I use GCD dispatch_async it does not create a
NSThread, hence my category approach does not work. How can I achieve
the same while using GCD to handle concurrency?
In short, you can't. If you want to go forth and patch functions all over the various frameworks, then you should look up a library called mach_override. (But please don't.)
What I would like to detect is when a new block is added to GCD, and
when that block has been executed.
Since GCD uses thread pools, the act of adding a block does not imply a new thread. (And that's sorta the whole point.)
If you have some limited resource whose consumption you need to manage, the traditional way to do that would be with a limiting semaphore, but that is just one option.
This whole question just reeks of a poor design. Like the number of pthreads, GCD's queue widths are opaque/non-public. Your previous solution was not particularly viable (as discussed), and further efforts are likely to yield similarly poor solutions. You should really rethink your architecture such that knowing how many threads are running isn't important.
EDIT: Thanks for the clarification. There's not really a generic way, from the outside, to tell when all the "work" is done. What if an action sets up a timer that won't call back for ten minutes? At the extreme, consider this: the main runloop continues to spin for the entire life of the app, and as long as the main runloop is spinning, "work" could be being done on it.
In order to detect "doneness" your app has to signal doneness. In order to signal doneness, the app has to have some way (internal to itself) to know it's done. Put differently, the app can't tell something else (i.e. Frank) something it doesn't know. One way to go about this would be to encapsulate all the work you do in your app in NSOperations. NSOperation/NSOperationQueue provide good ways of reporting "doneness." At the simplest level, you could wrap the code where you kickoff work in an NSBlockOperation, then add a completion block to that operation that signals something else when it's done, and enqueue it to an NSOperationQueue for execution. (You could also do this with dispatch_group and dispatch_group_notify if you prefer working in the GCD style.)
If you have specific questions about how to package up your app's work into NSOperations, I would suggest starting a new question.
You can hook into the dispatch introspection functions (introspection.h, methods all start with dispatch_introspection), but you have to link with that library which is supposed to be only for debugging. I don't think you can include that in a release build. Your best bet would be to encapsulate GCD into your own object, so all your code submits blocks to execute through that object and it submits them to GCD after tracking whatever you're interested in. You won't be able to track thread consumption though, because GCD intentionally abstracts that and reuses threads.
I am newcomer in Objective C.
I have an object, that creates new thread via GCD with dispatch_async in default queue.
I use dispatch_semaphore_wait with timeout = 1sec in thread to check when I need to close this thread.
When i call "close" method, it send dispatch_semaphore_signal and thread closes. But sometimes thread lives some time after "close" method ended. How could I wait in my "close" method until thread ends?
Thx.
Canonical answer to such a question: What are you trying to do?
I ask this because, first, you should neither need to know or care that there is a thread backing a GCD request and when it exits - that's entirely up to GCD to manage.
Second, you should always be suspicious of code that uses explicit timeouts (other than "FOREVER"). If you have any reason to ask yourself "Why 1 second? What happens if whatever event I'm waiting for takes more or less time than this?" then you are engaging in the kind of thinking that leads to polling, and polling is just BAD BAD (evil, wrong) design for pretty much everything but writing certain kinds of device drivers!
A far more reasonable approach is to use a completion callback at the end of your operation to signal that it's done, taking a fully async approach to programming and also following, in the process, one of the fundamental design principles of GCD.
It sounds to me, and I'm just guessing here, that you're taking an existing programming paradigm or way of thinking and erroneously applying it to GCD. An understandable mistake, but a mistake nonetheless.
I'm trying a simple thread program.
I need to wait for a event and time delay. This time delay is varying. How to do this?
Can anyone explain with a sample program? I know how to spawn a thread with NSThreads as well as through NSInvocationOperation.
If you need to wait for a timeout consider using NSTimer. You can use setFireDate method to modify time delay.
For asynchronous events there's a lot of way to solve the problem, according to what you need in your program: first of all you may simply setting a delegate that receive a message when something happen in your class. If you need something more complex (in order to avoid race conditions or deadlocks) you may consider use NSNotificationCenter or NSConnection.
I'm trying to set up a thread that stays idle until new data it's available. What it's the best approach for this in Objective-C? Till now I tried to make a simple run loop
while(YES) {
if(isDataAvailable) {
//process data
}
}
However this has an huge impact on performance, my FPS drops from 40 to 20 and the interface becomes unusable (even if the actual data process happens once in a second or so and it's not very intense for the CPU. I tried to add [NSThread sleepForTimeInterval:0.01] at the end, but this way I lose data packages ('process data' refers to some streaming related operations, queue and unqueue data packages), however the FPS returns to normal.
I'm fair new in Objective-C and I was thinking maybe there is a better way to do this? I also had a look over NSRunLoop, but didn't manage to make it work as a run loop :), only attached a timer to it that doesn't do more than my [NSThread sleepForTimeInterval:0.01] thing.
Any help it's highly appreciated:D
If you need to keep the seconary thread alive, you definitely want to use a real runloop:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW1
Basically, just create and start your thread, set up an autorelease pool, then run your runloop for some set time amount. When the time expires, you check to see if you should exit your thread, or enter into the runloop again.
As Marcelo points out though, there are more modern approaches to achieve concurrency (GCD and async dispatch being a couple of examples) so maybe investigate other forms of concurrency as well.