I'm new to iOS development (and Obj-C), and I'm trying to port an existing C program to iOS.
The C program usually runs in the console, but I want to make a UI for it on the iPhone. I've already ported the C code, and when the simulator is run I can get the printf output in the console window. I want to avoid changing the original code as much as possible, so this is my plan:
The program takes some time to execute, so I think I need to run it on a seperate thread. It look likes I'll only need an NSInvocationOperation to call it's main method.
I will redirect stdout to a pipe.
On another thread, I will read from the pipe, and throw this to the UI. I'm not sure what might be the best concurrancy API to use for this.
Is this a good strategy for the iOS, or is there a better alternative for porting this? Are there any pitfalls I should look out for?
For concurrency, use the dispatch queues for quickest programming. See this guide: http://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/Introduction/Introduction.html
To print to the screen, you could do this in many different ways, but just use a UILabel if you just want get text up there right away. You can also format it nicely later.
Main pitfalls for multithreading are like on any OS - locking any data models that have simultaneous read/write. You can use #synchronize or make your dispatch queues thread safe by using dispatch barriers also noted in the linked guide above.
Related
Need your help.
In my application, i want to implement a background process which keeps running continuously and downloads the updated data and stores it in document folder.
And my main thread should keep checking the document folder and display the updated data in view control.
The child thread should end once the view disappears. and start again once the view appears.
What is the best way to do it? NSThread or NSOperationQueue? What precautions are required?
I also have to access few variables of the class. So is should be thread safe.
Thanks in advance.
Regards
If you do not need to update a progress bar or something in iOS5 there is one great API method + sendAsynchronousRequest:queue:completionHandler: that allows you to run async download as a block inside NSOperationQueue. If not you should look into third party libs such as ASIHTTP request or https://github.com/AFNetworking/AFNetworking(probably better the last one) or you need to build you own download manager, not a simple task
there are two ways to do it..
First: You use NSOperationQueue which is a bit bulkier as it is build on GCD but does have some extra features.
Second: You use GCD (grand central dispatch) looking at requirements I would say GCD seems fine as you can easily access any thread(main or background) this would be slightly quicker.
You can have a look at - (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg This method creates a new thread in your application, putting your application into multithreaded mode if it was not already. In your viewDidDisappear, you can stop the task when your view disappears
From Apple Docs. Apple encourages to investigate the alternative Mac OS X technologies for implementing concurrency. This is especially true if you are not already familiar with the design techniques needed to implement a threaded application. These alternative technologies simplify the amount of work you have to do to implement concurrent paths of execution and offer much better performance than traditional threads.
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/AboutThreads/AboutThreads.html#//apple_ref/doc/uid/10000057i-CH6-SW2
Is there a way to implement non-blocking / asynchronous execution (without fork()'ing) in Perl?
I used to be a Python developer for many years... Python has really great 'Twisted' framework that allows to do so (using DEFERREDs. When I ran search to see if there is anything in Perl to do the same, I came across POE framework - which seemed "close" enough to what I was searching for. But... after spending some time reading the documentation and "playing" with the code, I came against "the wall" - which is following limitation (from POE::Session documentation):
Callbacks are not preemptive. As long as one is running, no others will be dispatched. This is known as cooperative multitasking. Each session must cooperate by returning to the central dispatching kernel.
This limitation essentially defeats the purpose of asynchronous/parallel/non-blocking execution - by restricting to only one callback (block of code) executing at any given moment. No other callback can start running while another is already running!
So... is there any way in Perl to implement multi-tasking (parallel, non-blocking, asynchronous execution of code) without fork()'ing - similar to DEFERREDs in Python?
Coro is a mix between POE and threads. From reading its CPAN documentation, I think that IO::Async does real asynchronous execution. threads can be used too - at least Padre IDE successfully uses them.
I'm not very familiar with Twisted or POE, but basic parallel execution is pretty simple with threads. Interpreters are generally not compiled with threading support, so you would need to check for that. The forks package is a drop-in replacement for threading (implements the full API) but using processes seamlessly. Then you can do stuff like this:
my $thread = async {
print "you can pass a block of code as an arg unlike Python :p";
return some_func();
};
my $result = $thread->join();
I've definitely implemented callbacks from an event loop in an async process using forks and I don't see why it wouldn't work with threads.
Twisted also uses cooperative multi-tasking just like POE & Coro.
However it looks like Twisted Deferred does (or can) make use of threads. NB. See this answer from the SO question Twisted: Making code non-blocking
So you would need to go the same route with POE (though using fork is probably preferable).
So one POE solution would be to use: POE::Wheel::Run - portably run blocking code and programs in subprocesses.
For alternatives to POE take a look at AnyEvent and Reflex.
I believe you use select for that kind of thing. More similarly to forking, there's threading.
POE is fine if you want asynchronous processing but using only a single cpu (core) is fine.
For example if the app is I/O limited a single process will be enough most of the time.
No other callback can start running while another is already running!
As far as I can tell - this is the same with all languages (per CPU thread of course; modern web servers usually spawn a least one process or thread per CPU core, so it will look (to users) like stuff it working in parallel, but the long-running callback didn't get interrupted, some other core just did that work).
You can't interrupt an interrupt, unless the interrupted interrupt has been programmed specifically to accommodate it.
Imagine code that takes 1min to run, and a PC with 16 cores - now imagine a million people try to load that page, you can deliver working results to 16 people, and "time out" all the rest, or, you can crash your web server and give no results to anyone. Folks choose not to crash their web server, which is why they never permit callbacks to interrupt other callbacks (not that they could even if they tried - the caller never gets control back to make a new call before the prior one has ended anyhow...)
First of all, I am a a very new Objective C/Cocoa iOS Developer but I've written C/C++ applications before.
So I managed to run the Rabbitmq-c (http://hg.rabbitmq.com/rabbitmq-c/) client inside my iPhone App, and I can connect to Rabbitmq directly from my app and even consume a queue item. So all's good.
Now my problem is, my iPhone app needs to use the rabbitmq-c library to poll for incoming messages in from the server. Probably there will be, an almost infinite while loop.
Do I have to take this to a new thread? Ideally, I want to wrap the rabbitmq-c class as an Async objective C class and use NSNotification (or something similar) to notify my UI. I'm a bit leery of creating a new thread, as I read about stuffs like Runloop etc can solve a lot of problems without using an extra thread.
What is the best way for me to go about this? Any examples of code or directions would be helpful. Please remember, I am not dealing with an Objective C code/Coca rabbitmq library here, I'm using C code inside my iPhone app.
Thanks
Subrat
don't block the main thread with your server polling.
since the operation never ends, create your own thread and run loop for this server polling. you can potentially use the run loop (each thread has one) instead of the infinite while. the alternatives involve regularly spawning threads. it's easiest to just use one thread for this.
once you have an update, post the notification (if you choose NSNotification) from the main thread -- UIKit is meant to operate from the main thread only.
for samples, i'd begin with samples related to NSRunLoop and CFRunLoop.
good luck
You can also create custom delegates for updating the UI, or the stuff related to UIKit.
Notifications might be a little easier to code and offer the advantage that multiple objects can observe one notification. With delegates, such a thing cannot be done without modifying the delegating object (and is unusual).
Some advantages of delegating:
The connection between delegating object and delegate is made clearer, especially if implementing the delegate is mandatory.
If more than one type of message has to be passed from delegatee to delegate, delegating can make this clearer by specifying one delegate method per message.
Or other way is to write method to receive messages. This method can have infinite loop.
Later you can put this method in background thread like this.
[self performSelectorInBackground:#selector(receiveMessages) withObject:nil];
I am currently trying to build a (simplified) stock app (like the one built-in on the iphone). I setup a simple server with a REST-interface which my app can communicate with.
However I am struggling to find the right/best way to build this kind of (streaming data consumer) client on the iphone.
My best bet at the moment is to use a timer to regularly pull the xml payload from the server (the connection is async but the xml parsing is not therefor the interface is blocked sometimes. I am a bit shy of thread programming since I learned some lessons the hard way on other platforms).
I read about websockets but it is not clear for me if and how they are supported on the iphone.
How would you do it?
Any hint would be appreciated, Thanks.
websockets aren't going to help you -- that's a server-side technology to make a socket-like interface work over HTTP.
If you don't want to block the GUI, you need to use another thread. You are right to be scared of doing this, so share as little as possible (preferably nothing) between the two threads. Use a message passing mechanism to get information from the background thread to the UI thread.
Take a look at ActorKit: http://landonf.bikemonkey.org/code/iphone/ActorKit_Async_Messaging.20081203.html
Take a look at this question.
It talks about asynchronous vs synchronous connections. You will want to use an asynchronous call to get your data so you don't lock up your UI. You could use that in conjunction with a polling timer to get your data from the server.
You can find more info about the NSURLConnection in apple's documentation here
I have some slow internet task to save and load file, I'd like to do those slow tasks in some background thread. I am wondering whether that's doable, and if it is, any sample code?
Then after it is finished, I'd like it to notice back to the main thread, so that I could update the UI.
Take a look at NSURLConnection. It will load an NSURL (using NSURLRequest) in the background, and send delegate methods regarding its status.
Ultimately the device you are running your code on has a single processor and cannot possibly load large quantities (gigabytes) of data. The best route, by is likely that suggested by Ben (NSURLConnection asynchronously) which gives you the added advantage of being able to cleanly cancel and handle error messages. While it isn't technically threaded in the way you probably think you want it to be, it is well integrated with the event loop and is non-blocking. If that is still not enough, I would suggest looking at NSOperation and NSOperationQueue. You can fire off an NSOperation sub-class object and perform the download there (I would still advise doing it asynchronously there so as to enable canceling, pausing, etc).
Log in to the iPhone Developer Center and search for Introduction to Threading Programming. Or, maybe you can log in and use this link:
http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/Multithreading/Introduction/chapter_1_section_1.html#//apple_ref/doc/uid/10000057i-CH1-SW1
If you do decide you need a background thread even after using asynchronous HTTP calls to gather the data, don't forget to wrap the background thread code in a new NSAutoReelasePool and then release it at the end.