NSOperation and running a class with method - cocoa

Let's say I have a class and *classMain is an object for this class. Now this class as a instance method - performAction. So normally to run the method, I would do:
[classMain performAction]
Now if i want to use NSOperationQueue to run this, I would do:
NSOperationqueue *opQueue = [[NSOperation alloc] init];
[opQueue addOperation: classMain].
What i want to do is actually add [classMain performAction] to the queue, so I can run the method I want ?
Also is there a better recommend way of running threads ( so my application does not get locked) in 10.7 ?

There are lots of ways to run threads and to run various actions on different threads. You may find this resource helpful:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html
And if you just have a simple task that you want to run in the background without locking your app, you may find that the most straightforward solution is to use performSelectorInBackground:withObject:.
As for which approach is recommended, it really depends upon your specific use-case and what sort of work you are offloading to a separate thread.

Related

What happens in Xamarin when Forms.Init gets called and the function is already running in another thread?

I'm thinking about how to reduce the cost of loading Forms.Init during the start of my app.
There's some work my app does that I can already do without access to Xamari.Forms. I'm thinking about loading Forms.Init in parallel in another thread.
In case that thread isn't yet finished and I already need Xamari.Forms, I'm not sure what my option are at handling the event.
What happens in Xamarin when Forms.Init gets called and the function is already running in another thread? Or are there otherwise best practices of dealing with loading Forms.Init in parallel to other work?
Forms.Init() calls the private SetupInit() which runs platform dependent code ranging from getting an Android Context, registering renderers, adding log listeners, etc...
Assembly callingAssembly = Assembly.GetCallingAssembly ();
SetupInit (activity, callingAssembly);
There are no callbacks or events tried to the competition of Init other then its synchronous completion, but there is a boolean flag that can be checked:
global::Xamarin.Forms.Forms.IsInitialized
But, depending upon platform, this flag can be set at the beginning of the method or at the end and also note there is no lock on setting this flag (which would cause a performance hit).
So, if the other code you need to run can be done completely without Forms, yes, you could do run this in parallel.
Your Application subclass and its LoadApplication step, of course, should not be done until Init() is finished.
re: https://github.com/xamarin/Xamarin.Forms

Can I use the same instance of EKEventStore on different threads?

I was wondering if it is safe to use a single instance of EKEventstore on different threads? I can't find anything about it anywhere.
I would be intending to get a unique EKCalendar instance on each thread.
The descriptions of enumerateEventsMatchingPredicate:usingBlock: and eventsMatchingPredicate: in the EKEventStore reference imply that this is safe to do:
This method is synchronous. For asynchronous behavior, run the method on another thread with dispatch_async or NSOperation.
I'm currently doing this in one of my apps and it appears to be working.

What would be a thread-safe way to save a context form Core Data?

I have a NSOperationQueue set to NSOperationQueueDefaultMaxConcurrentOperationCount. It is filled with NSOperation objects (nothing weird so far). I subclassed the NSOperation to do some background tasks.
Download data from the internet.
Parse the data so I can read it.
Create a NSManagedObject:
[NSEntityDescription insertNewObjectForEntityForName:#"Channel" inManagedObjectContext:context];
Save it with the context.
[managedObjectContext save:&error]
I like this all to happen in the background so the UI won't get blocked. I read this article about concurrency with core data, and as far as I understood it. The best way would be to create a new NSManagedObjectContext in every NSOperation, but share the same persistent store coordinator.
That's easily done, however, when it comes to saving the context it says in the documentation it is error prone to do so. So my question is the following:
If I have different operations running in the NSOperationQueue, could those operations interfere with each other while saving the managed object context? Or does it wait to execute the following operation till the saving has been complete?
Can I safely save the context in a NSOperation? Or is it really bad practice?
I hope someone can shine a light on this matter, because I am really stuck at the moment.
What you need to do is the following:
Create a managed object context for each NSOperation. Create this new context on the main method, because this is when it's executing on the right thread.
Assign the context persistent store coordinator.
Create an observer to receive the NSManagedObjectContextDidSaveNotification. This is the only way the main context will know at the time the changes were made on the NSOperation's context. Make sure the merge call is made on the thread/block the merging context lives in. If you are merging with the main thread's context, call the mergeChangesFromContextDidSaveNotification: method on the main thread with the notification from the NSOperation's context.
Also, ask yourself if you really want to have all these operations working concurrently. Per the documentation:
The default maximum number of operations is determined dynamically by the NSOperationQueue object based on current system conditions.
You do not have control over how many NSOperations will be operating at the same time. If this is not what you want, you might be better if you just go with a serial NSOperationQueue (maxConcurrentOperation=1), considering the fact that you are going to be locking the database to do the save, and also because you have networking being done as well.
You can safely save inside the NSOperation's main method, if you take the precautions mentioned above.

CoreData in one single separate thread

What I want in short is:
Core Data that runs without blocking the main thread
entities with relationships
bindings in InterfaceBuilder
I have tried 'everything', but it turned out that there are too many difficulties with Core Data on two or more threads and two NSManagedObjectContexts and bindings and entities with relationships and so on. These threads can make CoreData very complicated.
Nevertheless I want to use Core Data and I want it to run in the background for good UI response.
So I wonder, is it possible to completely run everything related to Core Data in one separate thread, which is not the main thread?
I will send everyone 50 bucks, if I finally find a solution that works...
I used two NSManagedObjectContext instances to push some longer lasting data tasks onto another thread with Grand Central Dispatch.
As long as you be careful to merge this context with the one on the main thread used to fetch data then you should be able to get some performance that way.
I am not sure if this can help you, but perhaps you can create a new NSOperationQueue and add whatever core data functions you need to in the background. So in your class have a property that is NSOperationQueue, then in the -viewDidLoad methods, you create new one:
myOperationQueue = [NSOperationQueue new]; Whenever you want to do an operation you can add it to the queue and I believe that it will execute on a separate thread (self.myOperationQueue addOperation: someFunction) and if you want to interact with the main thread, then call assert([NSThread isMainThread]) in the beginning of your method call. I am using Core Data and threading in a different way, but from the second thread I am able to create a temp object that the NSManagedObject is created from.

Cocoa Controllers - best practice for notifying on completion, for disposal?

I have an ObjC controller object.
After alloc/init of the object, I get it to do a job asynchronously:
[myObject doSomeThingsOverTime];
The method sets things in motion, and then returns immediately.
Question: what is the best way to be notified of the result in the future, so that I can release myObject and react to the work having been completed? Should I observe/post notifications? Or supply the object with a method to callback? Or other?
I'm personally a fan of the notification center route. It allows for more than one observer (may or may not be relevant to you).
The delegate route is also valid, and is used quite frequently in the frameworks.
I think it comes down to personal preference. If it's your own code, you should go for what's most readable and simple for your particular situation. I don't think one is more or less valid than the other.
Have you looked at the NSOperation and NSOperationQueue classes? You can observe the isFinished of an NSOperation object so you will get notified when it is completed.

Resources