Using threads in iPhone, do i need them in this case? - iphone

I have an opengl game, on top of it i am placing an small view that connects to the internet, retrieves data, with part of that data it connects again to retrieve an image and then displays it inside the view.
All this calls are asynchronous. Do i have to also use threads? What should i put inside in another thread?
Thanks

Nope, NSURLRequest is asyncronous, you just say what delegate it should use when receiving data and take it from there :-) No need for more threads to handle that

Related

crash bug because of using CATiledLayer and Core Data on iOS5

I am using CATiledLayer to render NSManagedObjects.
But you know, CATiledLayer render objects in background threads. This make my app crash on iOS5
I know that I should use separated NSManagedContext for each of threads but this way make performance get bad. (because I have to save the NSManagedContext more often to transfer data to other threads).
Do you guys know the better way to work around my problem? Please help!!!
Sorry for my poor English!
NSManagedObjectContext is not thread safe, nor are NSMangedObjects. You should create a MOC on the background thread, pass in any IDs (which ARE thread safe), and load them on the background thread context.
UPDATE:
One alternative is to create plain old obj-c objects, or even just a regular NSDictionay, which contains the necessary data and pass those to the background thread. So after your MO is populated, create a POOCO, copy in the necessary data, and pass that to your background thread for processing. This will avoid disk access.

Adding a lot of data to core data while keeping the UI responsive

I'm looking for a way to add a whole load of data to core data while keeping the little activity indicator spinning on the UI. I tried adding the data on another thread but since learned that core data is not thread safe, and I get all kinds of errors. Can anyone suggest another approach to this?
Thanks in advance.
Core Data is not thread-safe, but that just means you have to code appropriately, rather avoiding them entirely. To keep your UI responsive/up-to-date, you'll need to use threads.
Apple's documentation on the subject is here, and this blog post is an excellent walk-through of using multiple threads with Core Data, and some of the pitfalls involved.
You need to use a separate managed object context for each thread. There's some additional work you need to do to make changes from other contexts available to your main thread's context: see Concurrency with Core Data for a full discussion.
Most useful example is a core data XML downloading from iOS sample code. If u don't have access, please let me know and I will write here is a main structure of it.
There is a complex custom delegate techniques from u UIviewController to nsoperation delegate, this is important for u to start showing content immediately to user and show a progress of sync.
In AppStore u can see my "snow IXC" app, where u can see this techniques implemented for indicate user in their UIviewController about progress. It's free for downloading.
This is how I avoid background threads with a loading indicator (I use DSActivityView but this should work with other implementations):
In your code when you are going to be displaying the indicator run all the code to show the indicator first. After that code have a separate method call to do all the loading work. Call it by using the method:
[self performSelector:#selector(loadMethodName) withObject:nil afterDelay:0.0];
Normally the app will go straight into the loading code without waiting to show the indicator view. By calling it this way it will first finish displaying the indicator before it moves into the loading code.

Write/Save file to iPhone

I am currently saving images to the iphone's local space whenever I finish loading them. I was wondering if I need a separate thread to do that. I.e
The iphone can be requesting multiple images at the same time and when they are loaded, I call the save to HD method.
Since there are a lot of save to HD method being called at the same time, does anyone think I need a separate thread for each save to hd calls or somekind of queue that stacks the objects before being processed ?
Thanks.
There is NSOperationQueue class which allows you to run operations in background:
http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/NSOperationQueue_class/Reference/Reference.html
See this answer: NSURLConnection delegation and threading - iPhone

ScrollView content async downloading problem

I have UIScrollView with lots of UIImageView inside. In the loadView method I assign some temporary image for each of subview UIImageView images and starts several threads to async download images from internet. Each thread downloads and assign images as follows:
NSData *data = [NSData dataWithContentsOfURL:URL];
UIImage *img = [UIImage imageWithData:data];
img_view.image = img;
Here is the problem - I expects picture will changed after each image downloaded by I can see only temporary images until all images will downloads. UIScrollView still interact while images downloads - I can scroll temporary images inside it and see scrollers and nothing blocks run loop, but downloaded images doesn't updates..
What I tried to do:
Call sleep() in the download thread -- not helps.
Call setNeedsDisplay for each ImageView inside ScrollView and for ScrollView -- not helps.
What's wrong ? Thanks.
Update. I tried some experiments with number of threads and number of images to download. Now I'm sure -- images redraws only when thread finished. For example - if I load 100 images with one thread -- picture updates one time after all images downloads. If I increase number of threads to 10 -- picture updates 10 times -- 10 images appears per update.
One more update. I fixed problem by staring new thread from the downloading threads each time one image downloaded and exit current thread (instead of download several images in one thread in the cycle and exit thread only when all downloaded). Obviously it's not a good solution and there must be right approach.
I would discourage use of threads for this usage, and use an Asynchronous API for data retrieval on the network.
NSData *data = [NSData dataWithContentsOfURL:URL];
This function call sends some data out a socket then sits there and locks the thread until it receives a response. If you don't make any synchronous calls you don't have to worry as much about locking the UI Thread and your problem becomes much simpler.
I would use the ASIHTTP Library or NSURLConnection to access your data, and do all of your updating on one thread. There is a slightly learning curve with the API's but it's substantially smaller than managing threads correctly. I would strongly recommend the ASIHTTP Library, it just rocks. You can set the request delegate to a progress widget and throttle your connection for edge usage.
Hi Newbee (no phun intended)
The situation you describe sounds like a candidate for NSOperation and NSOperationQueue
You can simply "load" everything off to these methods and have them figure out how best
to retrieve the picture. If you keep building new threads, then at some point you loose the advantages of threading, i.e. the overhead grows for each thread and there is only so much CPU time to go around.
Start out by sorting the list of URL's for the pictures so that the ones furthest away from the user (in a scrollView sense) get's loaded last, then start adding the load operation off to an NSOperationQueue and then start the Operation. These classes will then balance things out and save you a ton of coding the logic to deal with scenarios that could erupt.
I found this helpful some weeks ago:
NSOperation tutorial
Marcus Zarra lays out a nice simple example to get you started.
EDIT: Whoops... and to answer your question:) if this does not result in your pictures updating, then you might need to send a specific "update" message when the operation is done.
If this is a large part of your app I would recommend you build a PictureObject and move the functionality inside that. So when adding a PictureObject you instantiate it with a URL and it displays a dummy picture as it's view. The you hand this PictureObject over to your NSOperation who retrieves it's URL loads the picture and sets it on the PictureObject.
This way it is async all the way and you don't have to deal with loops or testing if picture is downloaded etc. etc.
Hope it makes sense.

Save sequence images to iphone

I make screen shot with iphone camera use the UIGetScreenImage()method, I want to make this images sequence to video, but the memory is limited , i think write the image data to documents maybe a good choice for me. so when capture the image use UIGetSreenImage(), start a new thread to write the image data to documents, but this will delay the thread which used to capture image.
I don't know how to deal with this issues, Would you give me some advises? any reply will appreciate.
Foremost, I'd stay away from UIGetScreenImage() if you can, at least if you plan on releasing your app to the App Store. UIGetScreenImage() is not a public API, and it's one of the most likely "forbidden" APIs that Apple would reject your app for using.
If you want a screen shot (i.e. what the user sees on the device's screen), I think the approach that you've laid out works well, but you're going to need to get a graphic representation of the UIView that contains all your other views.
All UIView code must be on the main thread, though. You can do your file I/O on the background thread, but the actual getting of the image will have to be main thread.
How about NSOperationQueue?
Whenever the screen is captured and an image is created, an NSOperation which writes an image into documents is added a NSOperationQueue.
And I think you should find the best number of the max concurrent operation count (NSOperation's setMaxConcurrentOperationCount).
The max concurrent operation count depends on your app.