How to properly multi-thread with Core Data? [closed] - iphone

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 11 years ago.
I'm having a lot of issues with trying to perform some core data operations in a threaded NSOperation.
Currently, I have created a managed object context in my app delegate that is purely used on my threaded NSOperations. I setup a NSOperationQueue with a max concurrency of 1 so each action is performed serially. For each operation (that gets data from the internet and creates new managed objects), I pass it the context to use. Once the new objects have been created, I save and reset the context for the next operation to use. However, I'm intermittently getting malloc errors while doing this, and I've spent days trying to figure it out, and it would appear to have something to do with how it is threaded.
The errors I'm getting can be seen in this related stack overflow question.
The malloc error is occurring when I'm simply setting a managed object's property to an NSNumber object. It is also the first time I'm setting that property so it is nothing that I am over releasing myself! I can't figure it out at all, and I can't reproduce the error using GuardMalloc, it just doesn't occur! It's as if the error is happening somewhere else that is being triggered, but I have no idea where!
All I can deduce then is that the error is somehow connected with how I've set up the whole thing. I have tried running the operation myself instead of adding it to the NSOperationQueue and it appears to work fine (although it hangs the main thread!).
I also need the context to inform other contexts in my app when saves have been made, so I observe it's NSManagedObjectContextDidSaveNotification notification. However, since saves are being performed in the NSOperation (other thread), will there be problems with this as notifications are only dispatched on the thread it's running in?

Have you read the Multi-Threading with Core Data section of the Core Data Programming Guide?

Resurrecting an old question, but this might help someone - I ran into similar problems with the same setup described here (dedicated context for each NSOperation, max concurrency of one), and I found out that it was due to the fact that I was creating the NSOperation-dedicated context on the main thread, and then I tried to use it in an NSOperation thread. Once I moved context creation into the NSOperation's main function, the problems were gone.

Right, I've managed to get it all working now, much to my relief. After days of messing around, I decided to rewrite all the code to do with the threading and core data and I'm no longer getting the malloc errors. It is a rather complex setup so there must have been something pretty obscure in there!

Related

What does it mean that ARSession.run(_: options) runs asynchronously after its called?

The last sentence of the Apple Documentation for ARSession.run(_:options) in the the discussion section states:
ARSession.run(_:options)https://developer.apple.com/documentation/arkit/arsession/2875735-run?changes=latest_minor
”After you call this method, the session runs asynchronously.”
What do this mean?
Does it mean it runs on a different thread from the main forever?
Or
Does it mean that while it is transitioning from the previous session to new session it will be rerunning on a different thread?
Or
Does it mean something else?
I really want like to know/understand and would really appreciate any kind soul out there who would like to give some insight:-)
Thank you to the kind ARKit community,
We all learn by sharing what we know
Smartdog
“(A)synchronous” doesn’t have to mean multithreaded.
I’m pretty sure all they mean by that is:
the run(_:options:) call returns immediately
the session is an ongoing process (at least partly in the main run loop, since it has per-frame callbacks, but possibly also involving other threads you don’t see)
This would be in contrast calls that are “synchronous” meaning that all effects of the call complete before it returns.

Data driven view iOS app

I am new to objective-c/cocoa programming. I am making an application which is to constantly sync with a server and keep its view updated.
Now in a nutshell, heres what I thought of: Initiate an NSTimer to trigger every second or two, contact the server, if there is a change, update the view. Is this a good way of doing it?
I have read elsewhere that you can have a thread running in the background which monitors the changes and updates the view. I never worked with threads before and I know they can be quite troublesome and you need a good amount of experience with memory management to get most out of them.
I have one month to get this application done. What do you guys recommend? Just use an NSTimer and do it the way I though of...or learn multithreading and get it done that way (but keep in mind my time frame).
Thanks!
I think using separate thread in this case would be too much. You need to use threads when there is some task that runs for considerable amount of time and can freeze your app for some time.
In your case do this:
Create timer and call some method (say update) every N seconds.
in update send asynchronous request to server and check for any changes.
download data using NSURLConnection delegate and parse. Note: if there is probability that you can receive a huge amount of data from server and its processing can take much time (for example parsing of 2Mb of XML data) then you do need to perform that is a separate thread.
update all listeners (appropriate view controllers for example) with processed data.
continue polling using timer.
Think about requirements. The most relevant questions, IMO, are :
does your application have to get new data while running in background?
does your application need to be responsive, that is, not sluggish when it's fetching new data?
I guess the answer to the first question is probably no. If you are updating a view depending on the data, it's only required to fetch the data when the view is visible. You cannot guarantee always fetching data in background anyway, because iOS can always just kill your application. Anyway, in your application's perspective, multithreading is not relevant to this question. Because either you are updating only in foreground or also in background, your application need no more than one thread.
Multithreading is relevant rather to the second question. If your application has to remain responsive while fetching data, then you will have to run your fetching code on a detached thread. What's more important here is, the update on the user interface (like views) must happen on the main thread again.
Learning multithreading in general is something indeed, but iOS SDK provides a lot of help. Learning how to use operation queue (I guess that's the easiest to learn, but not necessarily the easiest to use) wouldn't take many days. In a month period, you can definitely finish the job.
Again, however, think clearly why you would need multithreading.

Core Data client+server/background saving/general import question

I'm working on a Core Data-based application that has a Mac application acting as a 'server' and an iPhone as a client. Everything is going swimmingly, except I'm running into performance issues.
When the user taps an object, the server must return some objects related to that object (nothing too heavy, usually 3-4 objects) and show a UI to choose some options. This needs to be as fast as possible. The round-trip time to the server, the server pulling the data, formatting it, returning it to the client, and the client creating NSManagedObjects from the data (which cannot be optimized further) is about 200 ms. The code relating to presenting the UI (which cannot be optimized further, again) requires around 150 ms. On an iPod touch 2G running iOS 4.0, the single line of code saving the managed object context after the objects are imported is taking anywhere from 150-200 ms.
To me, this screams that I should be backgrounding the managed object context saving. However, as far as I understand it, that won't really meet my needs. If I want to save the managed object context on a background thread, then all the objects in it must have been created on a background thread in a separate managed object context, so I won't see any speed gain because it will still take 100-200 ms for the save to occur, and I'll be seeing even more overhead because I'll still need to tell my main thread to update it's managed objects from the backgrounded managed object context's save before my view controller sees that it needs to refresh itself.
Am I missing an obvious solution? Is there something about Core Data I could use in this situation that would help? I hate to throw such a general question like this out there, but I'm at a complete loss where to go from here.
Sounds like you need to move the entire server communication to a background thread. If you did that then the entire UI would be responsive no matter how long the communication with the server took.
To do this, you stand up a second NSManagedObjectContext on the background thread connected to the same NSPersistentStoreCoordinator. Then you perform your server communication on that background thread (it might even make sense to use an NSOperation) and save the changes.
Your main thread and therefore main NSManagedObjectContext listens for save notifications and when it receives one it updates the main thread and UI. This will eliminate any freezing you are seeing and the processing time becomes mostly irrelevant.

iPhone performance optimization best practices [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I was looking for a book, text, post or something talking about iPhone optimization but I couldn't find anything except for Apple documentation.
I think it would be great to talk about which are the common steps you do when optimizing your apps performance. I'm now trying to improve my app memory usage and I've figured out it is really difficult when your app is complex.
How do you handle view creation and destruction? Are you doing it by yourself or do you delegate on iPhone navigation controller?
Do you use any trick to free some memory in your app?
To optimize the memory usage, avoid using auto-released objects.
If you don't need an object anymore, release it explicitly, so the memory will be reclaimed immediately.
Otherwise, the object will stay in the pool for an unknown time.
Note that this will optimize your application's memory usage, but not the performances.
Releasing explicitly objects may slow down your application.
You'll sometimes have to decide if you want a faster application, or an application that uses less memory.
Also try to use C code whenever possible. For instance, if you just need to store objects in an array, don't use a NSMutableArray unless you rely on a particular method.
If not, use 'id *' variable, and use malloc() and free().
Hope this helps a bit... : )
If you have a loop which might be executed many times over, it might be worth it to manually manage the NSAutoreleasePool in that case. More often than not you end up with a lot of auto-released objects (remember Foundation etc. generate auto-released objects, too) and waiting for your thread to end or control to return to the run loop could cause memory problems and slow your application. There is no guaranteed recipe for success here, so you might have to probe a bit.
One of the huge memory eaters are images, and everything that has to do with them. If you have a UITableView with hundreds of rows and each cell containing an image, you might not want to keep them all around in memory. You could keep a cache of those images in the file system and load the images as needed. Disk I/O might be relatively expensive, but if you watch the memory notifications closely and read ahead wisely, you'll hardly notice a performance impact.
Key techniques to remember when trying to reduce your app's memory usage are using the static analyzer (Cmd+Shift+A) and Instruments, especially the object allocation instrument.
One thing I try to force myself to do is avoiding instance variables whenever possible. They make your code harder to maintain and consume memory because they're usually not deallocated until their owner. Try to avoid unnecessary instance variables, or try to release them early if they can be recreated (from disk, for example).

Running a socket stream in a thread

I have an application that opens a connection with 2 sockets (in and out) and I want to have them working in a thread.
The reason that I want them to be in a separate thread is that I don't want my application to freeze when I receive data, and this can happen anytime as long as the application is running.
Currently I have a class that handle also network communication and I run this class in an NSOperation, I'm not sure if it's the best solution.
I'm not very familiar with threading so guys if you could give me some help I would be very grateful.
Thanks
First, you should know that you can use the same socket to send and receive data — they're generally bi-directional. You should be able to share a reference to the same socket among multiple threads of execution.
Second, unless you'll be receiving large amounts of data and have experienced performance issues with your UI, I would delay optimizing for it. (Don't get me wrong, this is a good consideration, but premature optimization is the root of all evil, and simpler is generally better if it performs adequately.)
Third, NSOperation objects are "single-shot", meaning that once the main method completes, the operation task cannot be used again. This may or may not be conducive to your networking model. You might also look at NSThread. The fact that you already have the functionality "factored out" bodes well for your design, whatever turns out to be best.
Lastly, threading is a complex topic, but a good place to start (especially for Objective-C) is Apple's Threading Programming Guide.