MATLAB UI callbacks (e.g. WindowKeyPressFcn) can be interrupted by newly triggered callbacks. This is very useful for terminating code which is taking too long to run. Is there any way to programmatically trigger a callback event?
Note that, in contrast to the answers to this question, I am not asking how to run a callback function programmatically. I actually want to trigger the callback event programmatically, to make use of this interruptibility feature.
Callback interruption is initiated by other callbacks specifically because there can't be any other code executing while the callback is executing. If you're in a position to "programmatically" invoke a callback, you already have "interrupted" any other callback that might be in progress.
That isn't to say that you can't trigger UI callbacks programmatically. Callback handles stored in object properties like WindowKeyPressFcn generally feed into listeners for corresponding events for those objects. For example you can invoke WindowKeyPressFcn for the current figure using notify(gcf,'WindowKeyPress').
However if you're in a position to make that call, you can also do anything you'd like to in the interrupting callback. If you're able to run that line because you are interrupting a callback, you then need to consider what the callback will do when it resumes execution.
Related
User is playing a game against the computer. After user does something, (e.g. in button-pressed routine called User Plays), a button called Computer Play is enabled. When user presses it, the computer plays, and then enables user play. All routines essentially finish and wait for user input.
If, instead, I trigger the Computer Play button automatically from the bottom of the user plays routine, will I leave something on the stack? Will I be building up a huge series of nested functions and eventually run out of stack space?
No. Button IBAction methods are methods like any other. They get called, they execute their code, and they return. Their local variables get allocated on the stack, and then get popped off the stack when the function returns.
If you have memory leaks in your IBAction method they will occur whether the method is called from a button press or from another method.
If you don't have memory leaks, calling a button's IBAction method from another method won't cause a memory leak.
EDIT:
Note that if you have endlessly recursive code (where a method calls itself repeatedly, or method A calls method B which calls method A which calls method B and so on forever) then you can endlessly allocate more and more stack memory until you have a stack overflow and crash your program. However, you'll know about that pretty quickly. Your app will freeze for a few seconds and then crash, every time you go into endless recursion.
Every time you work with a recursion there's a slight chance something might go wrong. Your question could be answered differently based on how your code is executed on practice.
Do you use escaping callbacks or you just call your methods from within each other and so on. Please provide some code or at least pseudo version of it. The general answer for this will be - yes. You have a risk to run out of stack space if your recursion call is potentially infinite.
I'm considering using Quartz for an app but I need to get called back also when a triggered event ends (e.g. at the beginning I want to start and at the end to stop something). Is it possible? Thanks.
you can get notified with TriggerListener and JobListener
I'm working on a small project in which I need to execute a LOOP to ask questions, and during the LOOP I need to wait for the answer from user before I can perform the next operation.
Any of you could help?
The iPhone's object-oriented framework, Cocoa Touch, already includes the loop you need. There's a class called NSRunLoop that does exactly what you require: it waits for events from the user interface (among other things) and then calls your code to handle the events.
So don't worry about building this loop yourself. Apple has a tutorial that shows how you can build an app that waits for user input and does work based on that input.
You can set all your butons into disabled state:
[myButton setUserInteractionEnabled:false];
After loop is finished, just set it back to true state. This seems to be the easiest possibility.
I've been searching around the web for an answer to this one, but was unable to find an answer, on the other side I think it's something quite common thus there is a possibility I'm missing some keywords here. Anyhow, the problem is as follows:
When is control given to a callback function in ObjC (iPhone)?
Does it happen after control is given to a high up in the hierarchy class responsible for the runloop? Can it occur in the middle of another function call being executed?
As an example, let's take the NSURLConnection, we don't know or can't predict when it's going to call didReceiveResponse or the other callback methods, can it be the case that didReceiveResponse get's called when I'm in the middle of another function? (highly doubt that but was unable to find information on callbacks wating for the end of the run loop)
Cheers,
Kaspa
can it be the case that
didReceiveResponse get's called when
I'm in the middle of another function?
No, within a single thread, code is not executed in parallel. The runloop schedules the execution of all messages and dispatches them in sequences. Not even NSTimers are guaranteed to fire to the precision they are theoretically capable of because they have to wait for the runloop like everything else.
The callbacks will not be called from in a middle of your function, indeed. You have to give back control to the main runloop for it to process events, and call your callback.
If you want to know who exactly calls your callback, put a breakpoint in it, and check the stack trace.
The only time the didReceiveReponse will be called while something else is executing, is if you have launched the connection on it's own thread (typically in an NSOperation).
This is why when you do have connections in a background thread, you usually use something like performSelectorInMainThread to change the value for other parts of the application - though you can adjust properties directly if they are not marked nonatomic and are not mutable collections.
By default, basically all cocoa touch classes work entirely in a single thread, including many asynchronous operations like background network calls. The main exceptions are NSOperation and friends, and things related to NSThread.
The OS can do this by inserting its callbacks in the run loop schedule. There are also a few cases when one of your calls will also result in a callback on the same stack - for example, if you call resignFirstResponder on an object that notifies its delegate when this happens, such as UITextField.
A couple relevant blog posts:
quick intro to NSRunLoop
Friendly overview of Objective-C callbacks
I have an ai loop that I would like to write for my iphone app. I am under the understanding that this loop will take along time to make calculations and block the main application.
I want to put it in a different thread and run everything off events.
For example I would have an event that would be called when the players turn started. The AI thread would listen to it and react.
What is the best way for my ai thread to communicate with the main thread? I use NSNotificationcenter a lot but I am reading strange stuff like it will not fire the event on the right thread?
What is the best way to communicate through event like actions with threads?
My recommendation would be to use an NSOperationQueue for your AI processing actions. As the user performs actions, create an NSOperation which handles the AI processing in response of that event and add it to the NSOperationQueue. If there are dependencies between these actions, or if you wish to split your processing up into smaller sub-actions, you can set these actions to process only when certain conditions are met.
Operations placed within an NSOperationQueue will run on a background thread, so they will not block the main thread. For UI updates or other actions that need to be taken on the main thread, I recommend using -performSelectorOnMainThread:withObject:waitUntilDone: to call a method within your operation that posts a notification via NSNotificationCenter's -postNotificationName:object:. Have your view controller or other controller respond to these notifications and do what they need to in response to your AI routine's results.
Instead of firing up a seperate thread manually, I would urge you to consider using NSOperation / NSOperationQueue. It is much easier to work with, far less prone to errors and well documented with tutorials and examples all over the web.
You can use the methods - performSelectorOnMainThread: to execute a given method on the main thread, and - performSelector:onThread: or - performSelectorInBackground: to execute a method on another thread. Using these methods you can fire events across threads.
Note though, to use - performSelector:onThread: a Run Loop must be running on the target thread, else you method will not be executed.
I fire the AI in a background thread with performSelectorInBackground and each time the UI needs to be notified about something (the AI resulting action, a progress bar showing the AI working, etc) I use performSelectorOnMainThread:.
Of course, remember to create a NSAutoReleasePool in the background thread.