Objective-C console app that will never terminate while connected to Redis - objective-c

I have a Objective-C/Swift console application that I am updating to connect to Redis (pub/sub). However, the application exits prior to even connecting to the Redis server.
How can I have the application (main thread) essentially run forever without blocking the background threads (NSOperationQueue)?
I've developed something similar in C# and used the "Console.Read()" function to essentially wait forever. I tried using the same approach for this program with "scanf(...)" but that appears to block the execution of the background threads.
I found this question, Console App Terminating Before async Call Completion for C#. Is there anything similar in Objective-c/Swift?
Any input would be greatly appreciated.
Thanks!

[[NSRunLoop currentRunLoop] run];
Do that on your main thread. It'll never return.
If you have some code you want to invoke in the context of the run loop, use dispatch_after() or performAfter:... or variant therein.

Related

when I quit my application, how to ensure ongoing threads are not interrupted at a bad moment?

I'm new to threading, so there are a few things I'm trying to grasp correctly.
I have a windows form application that uses threading to keep my UI responsive while some server shenanigans are going on.
My question is: when I quit my application, what happens to ongoing threads? Will they run to completion or will the abruptly be interrupted?
If they are interrupted, what can I do to make sure they at least don't get interrupted in such a way that would corrupt data on my server (force them to run to a safe place in the code where I know it's ok to interrupt the execution)
You will want to keep a reference of said threads, and call .Abort() on them when you want to terminate. Then you put your thread's code in a try/catch block and handle ThreadAbortException's. This will let you clean up what you are doing and terminate the thread cleanly at your own pace. In the main thread, after you called .Abort(), you just wait until the thread is no longer running (by polling the .IsAlive property of the Thread object) and close your application afterwards.
A thread needs a process to run in. The process won't be able to terminate if you don't terminate all the non-background threads you have started. Threads marked as background thread will be aborted.
So, the behavior is entirely up to your implementation. If you want to close the application, you could wait for all threads to terminate by themself, you could set an event to ask them to terminate and wait or you could just kill the threads.
The UI thread will terminate by itself because it runs a messageloop that stops when requested by the operating system, also see wikipedia and this answer.

Is there a way to update GUI or use GUI while CPU is working?

The GUI of my program freezes while the program is doing its work. I created a mass import which can send X-thousand datarows via a called webservice into a database. The code is already very big and I cannot rewrite it for multithreading purpose.
I don't know how to do it. Any suggestions? If needed I will show some code, but at the moment I don't know what to show.
Firstly, you should rewrite it to use avoid synchronously doing this on the UI thread. If you do a lot of work on the UI thread, it simply will freeze the UI thread. There are a few options here:
If your web service proxy supports asynchronous calls, and if you're using VB 11, you can use Async / Await to call the web service asynchronously from the UI thread in an asynchronous method, and control will return back to the UI thread at the same point in the asynchronous method when the call has completed. It takes a little while to get your head round asynchrony, but this is probably the best option if it's possible.
You can use the Task Parallel Library to make calls on a different thread, but then you'll need to think carefully about how that thread is going to interact with your UI thread.
You can use BackgroundWorker to run some code on another thread, but report progress and completion back on the UI thread
You could potentially call Application.DoEvents between each web service call, to let the UI handle events. This is dangerous - it can lead to re-entrant code, so locks won't behave as you expect them to, and similar hard-to-diagnose errors. This should be your last option, if all else fails.

performSelector:OnThread:waitUntilDone not executing the selector all the time

I have an app where the network activity is done in its separate thread (and the network thread continuously gets data from the server and updates the display - the display calls are made back on the main thread). When the user logs out, the main thread calls a disconnect method on the network thread as follows:
[self performSelector:#selector(disconnectWithErrorOnNetworkThread:) onThread:nThread withObject:e waitUntilDone:YES];
This selector gets called most of the time and everything works fine. However, there are times (maybe 2 out of ten times) that this call never returns (in other words the selector never gets executed) and the thread and the app just hang. Anyone know why performSelector is behaving erratically?
Please note that I need to wait until the call gets executed, that's why waitUntilDone is YES, so changing that to NO is not an option for me. Also the network thread has its run loop running (I explicitly start it when the thread is created).
Please also note that due to the continuous nature of the data transfer, I need to explicitly use NSThreads and not GCD or Operations queues.
That'll hang if:
it is attempting to perform a selector on the same thread the method was called from
the call to perform the selector is to a thread from which a synchronous call was made that triggered the perform selector
When your program is hung, have a look at the backtraces of all threads.
Note that when implementing any kind of networking concurrency, it is generally really bad to have synchronous calls from the networking code into the UI layers or onto other threads. The networking thread needs to be very responsive and, thus, just like blocking the main thread is bad, anything that can block the networking thread is a bad, too.
Note also that some APIs with callbacks don't necessarily guarantee which thread the callback will be delivered on. This can lead to intermittent lockups, as described.
Finally, don't do any active polling. Your networking thread should be fully quiescent unless some event arrives. Any kind of looped polling is bad for battery life and responsiveness.

Saving managed object context creates deadlock in iOS 5's performBlock

I've been looking for a solution for this problem for a long time and have yet reached one.
I'm developing an iOS app with core data. I've created two managed object contexts (MOC) which point to the same persistent store coordinator. One MOC (referred as self.moc) is initiated with main queue concurrency whereas the other mov (referred as self.bmoc) is initiated with private queue concurrency. I've made sure that self.moc only runs on the main thread and self.bmoc only runs within its performBlock or performBlockAndWait block.
However, I've encountered this strange situation where my app freezes on the [self.bmoc save:nil] line. Since the save action is executed within the performBlock block, I don't see a reason for it to reach a deadlock. Since it freezes on that line, I can't receive an error even if I use [self.bmoc save:&error] rather than nil.
Below is the code which will reproduce the problem. Although I have many functions similar to the one below, only this one creates the problem. I fail to figure the cause of the problem and any insight is greatly appreciated. Thank you!
-(void)createEmptyUserData {
[self.bmoc performBlock:^{
User* user = [NSEntityDescription insertNewObjectForEntityForName:#"User" inManagedObjectContext:self.bmoc];
/* sets user object */
[self.bmoc save:nil];
}];
}
Note: This piece of code is executed in main thread.
There are two basic reasons for you to get a "hang" in that situation.
You have a nested call to performBlockAndWait or some other synchronous thread/queue call.
One of your blocks is not returning, and running forever.
Both of these can be easily seen by looking at the stacks of each running thread at the time of the "hang."
performBlock simply takes the execution block and adds it to a queue, then it returns immediately. Some other thread is then popping execution blocks off the queue and executing them.
performBlockAndWait executes in the context of the calling thread. Basically, it waits for currently enqueued execution blocks to run, then it runs the requested code on the current thread.
It des not return until the call is complete.
So, I'd bet you either have multiple nested calls to performBlockAndWait OR one of your asynchronous execution blocks is not completing.
Look at the stack at the time of the hang...
Alternatively, log your block execution, so you can see when each block starts and exits.

Using Appkit Framework in Launch Daemon

I want to use NSWorkspace to check if application is launched or closed.
But the process is Launch Daemon and Apple documentation says its not thread safe.
However, the part of code that makes use of Workspace will not be executed at start up or login time. It will be executed after some commands received from other application via BSD communication and process is background process without UI?
Is it safe to use Appkit framework in this situation? Only NSWorkspace API and no other? Alternate solution is Polling? What is your suggestion?
Generally you can use any code that isn't thread safe, as long as you are only doing one operation of whatever the unthreadafe operation is at any given time. I would go ahead and try it, and just be aware that whatever you are doing you can't do concurrently, if you absolutely need to do something concurrently you can try throwing a couple of #synchronized blocks around the code, either in callbacks of a long running background process, or delegate calls.