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 (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to