Xojo should add a new pragma which would cause the compiler to dispatch the code contained in the method to the main thread. In iOS, many block callbacks and delegate methods are called on private threads which lead to crashes in the Xojo app because the code is not managed by the Xojo runtime.
Currently the only to make code like this work is to add:
to the top of the method which will be called on the private thread. Combined with retaining any pointers to objects returned by the callback and setting a boolean variable, it is possible to determine when the callback is called and then use those objects on the main thread using Xojo.Core.Timer.CallLater as shown in the attached class. Unfortunately, this approach only allows the creation of certain objects where there will only be a single callback, and not multiple or repeated callbacks.
Adding a #pragma DispatchToMainThread (or similarly named #pragma) which caused the compiler to internally wrap the code in the method in a
so the Xojo code is called on the main thread would allow for the creation of many important classes in declares that are not currently possible such as the classes needed to access the Photos framework or the MultipeerConnectivity framework.
Using a properly designed interface and Sam Rowland’s Notification Center, you can make any method executable on the main thread no matter where it is called from.
It’s a very elegant and slick way to handle this problem. You are basically sending a message to the notification center that you want something to be executed on the main thread. In fact, the same object running the thread can also execute your code that is needed on the main thread.
As norman said, they tried this and the result was that the code execution was so slow, people begged them to remove it.
Norman, then is there some other way this should be accomplished? You guys could create all of the classes yourselves for us, but with the work involved in that it doesn’t seem likely to me since progress in that regard has been snails pace. There has to be a way to do this or Xojo created iOS apps will be cut off from many important and widely used features that are standard in Swift and Objective-C apps.
Jon, I’m not sure you understood the problem. The issue is that with these call backs we cannot control when they are called or where they are called, they are called by the Objective-C runtime on a private real thread, not a Xojo style thread. The Xojo runtime doesn’t like this and causes the app to crash with a variety of exceptions, making it nearly impossible to create declares classes for objects which use callbacks in this style. If this was with Xojo threads you are right, it would be straightforward to use timers and redirect the method calls to the main thread. Unfortunately this isn’t possible the the Objective-C callbacks.
Indeed, they don’t try to access the UI. The problem is that Xojo likes to use only one real thread (the main thread) and when any Xojo code is run on another thread weird things happen and the app crashes. With a pragma like this, the compiler could cause the Xojo code to be run on the main thread and prevent these crashes.
I don’t think you can move a process from one thread to another. A better request would be for a pragma that insulates a method from the Xojo framework. You would be sandboxed and probably severely limited in what you can do, but at least you could execute some Xojo code in a callback.
Well dispatch_async allows you to have the code executed on a different thread that you specify so I was thinking that having the framework do that for us with a pragma would be good. Simply insulating it from the framework would probably be a partial work around but I doubt that Xojo will do that because it would be so limited and would probably have some other hidden issues with it.
[quote]A pragma is not the right thing for this, I believe. Instead, it would be the stub code for the delegate that gets created for the call into this function that needs to include such safeguarding code.