Objective-C Blocks and different thread

I am trying to use Objective-C Blocks via Joe’s Plugin, but have run into a situation where the code appears to partially work.

I can pass the block to the API and it accepts it; however when it runs the IDE comes forward multiple times before Raising a StackOverflowException. Not a single line of my code in the referenced method actually fires.

Now I seem to recall this is because the OS is calling the block from a different thread and Xojo doesn’t currently handle this. I currently am aware of 3 ways of accomplishing what I want with this project, the 1st is far too slow and Apple recommend the second method, which uses blocks. The third method I’ve found online also uses blocks and gives me the same problem in Xojo.

So what I am asking, is am I right. Is this behavior because the OS is coming back into my application on a separate thread and secondly; is there anything I can about it?

Code?

Code?

Link?

Link?

Xojo is not threading safe.
If the callback comes on a other thread, you need to use a plugin to catch it.

[quote=338654:@Christian Schmitz]Xojo is not threading safe.
If the callback comes on a other thread, you need to use a plugin to catch it.[/quote]
He does:

The blocks plugin doesn’t do the thread handling.
It just calls back your delegate.

In my plugins I put a lot of work into retaining all parameters and do a call to the main thread passing those parameters and doing the event on main thread.

Yes and probably yes. There are some discussions on this forum that handling a background thread is not officially supported by Xojo and project code trying this could break in a future version.

Anyway, what works for me so far is:
• in your block method, disable StackOverflowChecking, BackgroundTasks and NilObjectChecking
• you must not address objects in the block, neither declared ones or Xojo instances and their properties
• you can declare objects if you only handle them via Ptrs anyway, but not when wrapped in a Xojo object wrapper.
• you can access class and module properties.

So, in the frequent case of a background thread receiving system values and you want to forward them to your code, write them into shared properties.

• In the custom classptr of the macOS class, I installed an event raiser method for each of those blocks. The implementation does nothing else than to read the saved values from the shared properties and raise an event where they are presented.

• The last action in the block method is then to call performSelectorOnMainThread with the selector of the event raising method.
I recently figured out (read that: had great help) how to use the ObjC framework methods to call a selector with each number of parameters so buffering in shared properties should be unnecessary, but I am not on my main Mac currently where I have that code.
Using GCD is another way to call a method on the main thread.

P.S.: And, as Christian pointed out, it is often necessary to retain objects received in the block method if they are being served autoreleased (and to release them after the event has fired of course).

1 Like

Thanks all for your help; I found a forth way of accomplishing what I wanted that was synchronous and didn’t require blocks.

It’s working perfectly (in 64-Bit, it’s broken under 32-Bit) and is 15x faster than the previous method; but of course requires 15x the code to get it working! Lol!

Thanks for confirming what I recalled about blocks; I’ve used them in the past with a majority of success. It seems like Asynchronous transactions are not easily possible and Ulrich’s workaround sounds like a lot of ma fan.