Run C function in background in Objective-C - objective-c

I want to call a C function in a Objective-C app. The function contains an endless loop. So I need to run this C function in background.
Here's my C function:
int go(){
for(;;){
//...
}
return 0;
}
And the call:
[self performSelectorInBackground:go() withObject:nil];
The function go() is called but it's not running in background (and the app stop working...).

Even in the background you probably should run something in an endless loop. However it is possible.
[self performSelectorInBackground:<selector> withObject:<Object>];
That is a nice convenience method to just throw a method to the background thread. But you also have access to Grand Central Dispatch that would let you put blocks of code into a background thread as well. You could even give it a private queue so it wouldn't block your background queue.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
// Your code
go();
});

Hmm, there may be an easier way, but...
- (int)doGo {
return go();
}
Then...
[self performSelectorInBackground:#selector(doGo) withObject:nil];
So, this answer really just highlights what I believe is the most fundamental problem with your provided code, but you should certainly see Ryan's answer and use GCD. performSelectorInBackground: really isn't all that great.

Related

dispatch_get_main_queue() in main thread

I have method which makes UI changes in some cases.
For example:
-(void) myMethod {
if(someExpressionIsTrue) {
// make some UI changes
// ...
// show actionSheet for example
}
}
Sometimes myMethod is called from the mainThread sometimes from some other thread.
Thats is why I want these UI changes to be performed surely in the mainThread.
I changed needed part of myMethod this way:
if(someExpressionIsTrue) {
dispatch_async(dispatch_get_main_queue(), ^{
// make some UI changes
// ...
// show actionSheet for example
});
}
So the questions:
Is it safe and good solution to call dispatch_async(dispatch_get_main_queue() in main thread? Does it influence on performance?
Can this problem be solved in the other better way? I know that I can check if it is a main thread using [NSThread isMainThread] method and call dispatch_async only in case of other thread, but it will make me create one more method or block with these UI updates.
There isn't a problem with adding an asynchronous block on the main queue from within the main queue, all it does is run the method later on in the run loop.
What you definitely don't want to do is to call dispatch_sync adding a block to the main queue from within the main queue as you'll end up locking yourself.
Don't worry if you are calling dispatch_async in main thread or not. iOS will put the block in a queue and execute the block in main thread.

ios stop 2 threads from using a method at the same time

We had a bug, and it destroys the looks of our UI, some of the UI elements overlap, or has been added to the subview twice. the bug is hardly reproduced so its hard to fix it. Now I thought of the reason, and probably the method that changes the UI are being called twice at the same time. And I was correct, I tried to create the bug programatically.
We have a bug which is caused by a method being accessed by different threads at the same time. To emulate this problem, and better understand it. see codes posted below.
When I do this, updatePresence Method call, my program works perfectly
ViewController.m
-(void)loadConversationScreen{
[conversationController updatePresence];
}
But when I do this, something goes wrong with my program
ViewController.m
-(void)loadConversationScreen{
[conversationController performSelectorInBackground:#selector(updatePresence) withObject:nil];
[conversationController updatePresence];
}
This is because the method is being accessed at the same time and and the instance of my UIView is being accessed/changed also at the same time.
How do I PROPERLY stop 2 threads from using a method at the same time?
How do I properly handle it in IOS(if there is no proper way, what are the work arounds), are there built in locks or somekind?
My app should support ios 4.0 and up
Advance thanks to all for your help.
The best thread lock for you is #sycnhronized(object) {}. This means only one thread can enter the code at a time. The object passed in is used to perform the lock; only one thread can enter a block protected by a particular object's synchronized at a time. The others will wait. This can be any Objective-C object, even a NSString.
Typically, you'd use whatever object you're trying to protect from multiple threads. You probably want #synchronized(self) {}:
-(void)updateVariables {
#synchronized(self) {
_foo = 1;
_bar = 2;
}
}
#sycnhronized is re-entrant in the sense that the same thread can call #sycnhronized as deeply as it wants, for instance:
- (void)a {
#synchronized(self) {
// entered "immediately" if called from b, where the #synchronized has
// already been called
_foo = _foo + 1;
}
}
- (void)b {
#synchronized(self) {
[self a];
}
}
For posterity and because I already typed it before reading your clarification, if you really cared only about updating the UI, you'd want to force your call over to the main thread instead like this:
- (void)someTask {
dispatch_async( dispatch_get_main_queue(), ^{
[self updateUI];
});
}
- (void)updateUI {
NSAssert( [NSThread isMainThread], #"called from non-main thread" );
// do UI updates here
}
As warrenm said you shouldn't update your UIView from a different thread than the Main thread (UI thread). Still, you asked if there is any workaround for what's going on. To be honest, you should try to, instead of blocking the access of the second thread to your method, understand why the methods is called twice. This is more a logical problem than anything else and you should try to fix that, instead of trying a shortcut.

App stops inconsistently at a call to dispatch_sync() [duplicate]

Im using XMPPFramework and in it's code there's a method like this:
- (NSDictionary *)occupants
{
if (dispatch_get_current_queue() == moduleQueue)
{
return occupants;
}
else
{
__block NSDictionary *result;
dispatch_sync(moduleQueue, ^{//IT BLOCKS HERE, WITHOUT MESSAGE
result = [occupants copy];
});
return [result autorelease];
}
}
[EDIT]
It blocks inconsistently, not always, since the app is not doing anything I pause it and I see the thread has stopped there, and it never continues to execute.
What is wrong? Any ideas?
Thanks
The behavior you explain perfectly matches with the one that appears when you try to send perform an operation on main thread via GCD while being on the main thread. So you should check if moduleQueue is the main queue, then this is it. Try checking if it is the main queue if it is, skip the dispatch_sync block.
Blocks sometimes need to retain variables to ensure they are available when they execute. If you use a local variable inside a block, you should initialise it to zero where you declare it outside the block.

App blocks while dipatching a queue

Im using XMPPFramework and in it's code there's a method like this:
- (NSDictionary *)occupants
{
if (dispatch_get_current_queue() == moduleQueue)
{
return occupants;
}
else
{
__block NSDictionary *result;
dispatch_sync(moduleQueue, ^{//IT BLOCKS HERE, WITHOUT MESSAGE
result = [occupants copy];
});
return [result autorelease];
}
}
[EDIT]
It blocks inconsistently, not always, since the app is not doing anything I pause it and I see the thread has stopped there, and it never continues to execute.
What is wrong? Any ideas?
Thanks
The behavior you explain perfectly matches with the one that appears when you try to send perform an operation on main thread via GCD while being on the main thread. So you should check if moduleQueue is the main queue, then this is it. Try checking if it is the main queue if it is, skip the dispatch_sync block.
Blocks sometimes need to retain variables to ensure they are available when they execute. If you use a local variable inside a block, you should initialise it to zero where you declare it outside the block.

Run an anonymous block on a specific background thread

At first glance it seemed like an easy question, but I just can't figure how to run an anonymous block on a certain background thread i.e. I am looking for the blocks equivalent of -performSelector:onThread:withObject:waitUntilDone:.
Related: Is it possible to associate a dispatch queue with a certain background thread, just like the main queue is associated with the application's main thread?
Edit Clarified that I am looking to run an anonymous block
I saw this function RunOnThread() recently in Mike Ash's PLBlocksPlayground (zip file, see BlocksAdditions.m):
void RunOnThread(NSThread *thread, BOOL wait, BasicBlock block)
{
[[[block copy] autorelease] performSelector: #selector(my_callBlock) onThread: thread withObject: nil waitUntilDone: wait];
}
This is what I was looking for.
There are a bunch of other very useful blocks related utilities in PLBlocksPlayground, most of which Mr. Ash explains in this post.
If I understand you right you should do this:
dispatch_queue_t thread = dispatch_queue_create("your dispatch name", NULL);
dispatch_async(analyze, ^{
//code of your anonymous block
});
dispatch_release(thread);
You also can write some method, which will take block to it, but you should know what type of parameters will it holds:
-(void)performBlock:(void (^)(SomeType par1, SomeType par2))block ToData:(Sometype)data;
You can call it with anonymous block:
[something performBlock:^(SomeType par1, SomeType par2){
//do your stuff
} ToData: data]
And in method you can call your block as a simple C function:
block(par1, par2);
A block is a function. Call it like you would call any other function.