Cancelling a loading loop in order to load something else
Cancelling a loading loop in order to load something else
- Subject: Cancelling a loading loop in order to load something else
- From: Keith Blount <email@hidden>
- Date: Tue, 18 May 2010 08:07:34 -0700 (PDT)
Hi,
I'm having problems getting my head around something that is probably fairly basic, but I can't find any obvious examples to give me the clue I need (no doubt because I'm using the wrong search terms). Essentially I need to add to my app the ability for the user to cancel what could potentially be a long and intensive loading loop when the user clicks to load something else, but I'm having difficulties coming up with a solution that works for this particular situation. Usually for this sort of thing I use a modal session and check that -runModalSession: returns NSRunContinuesResponse inside the loop, to see if the user has cancelled and the loop should be exited. But this doesn't seem to work for what I'm trying to do right now (or at least my attempts so far have had poor results). It may be that a modal session is still the right approach, but before I spend another day trying to get it to work properly, I'd be grateful if anyone could let me know if
I'm on the right tack or if I'm missing a better approach.
This is what I'm trying to do:
• In the source list of my app, the user can select multiple text documents.
• A loop is invoked in which each selected document gets loaded from a file on disk and combined into a single text storage, then displayed in a text view.
• There is the potential for hundreds of files to be loaded from file during this loop and combined into one text storage, which can take time. (A "loading" message gets shown while loading occurs.)
• During this loading, the user should be able to cancel the load by selecting other documents in the source list, and this is the refinement I'm trying to add at the moment and am finding difficult. The problem I'm having is that the same action that caused the loading loop should cancel it and set it up for a different load, if that makes sense.
In other words, what is the best way of doing the following:
• The user clicks on an item in the interface which calls method -foo:, which invokes a long loop that can potentially take a lot of time.
• The user clicks on another item in the interface which immediately cancels what -foo: is currently doing (causes it to exit its loop and return) so that it can call -foo: with new information to put through the loop without having to wait for the old loop to complete.
Pseudo code:
@implementation MyTableDelegate
- (void)tableViewSelectionDidChange:(NSNotification *)notification
{
// To further confuse things we only load anything after a slight delay, so that using the arrow keys to navigate quickly through the
// table view won't be slowed down by loading every single text.
[[MyOtherController class] cancelPreviousPerformRequestsWithTarget:myController];
[myController performSelector:@selector(doSomethingWithObjects:) withObject:[myTableController selectedObjects] afterDelay:0.1];
}
@end
@implementation MyOtherController
- (void)doSomethingWithObjects:(NSArray *)someObjects
{
[self showLoadingProgressIndicator];
[self clearOutSomeOtherStuff];
NSEnumerator *e = [someObjects objectEnumerator];
id obj;
while (obj = [e nextObject])
{
NSAttributedString *text = [self loadTextFromFileForObject: obj];
[combinedText appendAttributedString:text];
}
[self loadText:text];
}
@end
So, in the pseudo code above, how could I make it so that the user could still click into the table view while -doSomethingWithObjects: is looping through the objects it has already been passed from the last table-click, and so that -tableViewSelectionWillChange: will cancel the current -doSomethingWithObjects: loop and immediately call -doSomethingWithObjects: again with a different array? (-doSomethingWithObjects: may be called from other areas of the interface, too, though - not just from the table view.)
I've tried creating a modal session at the beginning of the loop and calling through to cancel it from the -tableViewSelectionDidChange: method before calling -doSomethingWithObjects: with the new objects, but it seems flaky (it sort of works but then the interface seems to freeze a moment afterwards). Also, -tableViewSelectionDidChange: isn't the only place the loading method can get called from - that is, in the pseudo code above, -doSomethingWithObjects: could be called from various other places, too, so it's almost as if -doSomethingWithObjects: needs to cancel itself if called a second time (whilst allowing the user to click elsewhere in the interface rather than freezing everything).
Should I forge ahead with trying to get a modal session working for this, or is there a better solution I'm missing?
Any pointers to examples or links that I may have missed or other suggestions much appreciated.
Thanks and all the best,
Keith
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden