Re: How to cancel a NSURL action
Re: How to cancel a NSURL action
- Subject: Re: How to cancel a NSURL action
- From: Marc Laffitte <email@hidden>
- Date: Fri, 2 Nov 2001 16:59:13 +0100
Following is a threaded solution. It may not be perfect because if
timeout occurs, I get two warnings like "class NSCFString autoreleased
with no pool in place - just leaking".
Beside this, in my case it works:
@interface MyDownloadManager : NSObject
{
NSAutoreleasePool *pool_;
BOOL downloadFinished_;
BOOL canceled_;
NSURL * url_;
id client_;
NSTimeInterval timeOut_;
NSTimer * timeOutTimer_;
}
- (id)init:(id)client;
- (void) download:(NSURL*)inNSURL;
- (void) setTimeout:(NSTimeInterval)inTimeout;
- (void) cancel;
@end
@implementation MyDownloadManager
- (id)init:(id)client
{
if (self = [super init]) {
downloadFinished_ = NO;
canceled_ = NO;
timeOutTimer_ = 0;
client_ = client;
}
return self;
}
- (void) setTimeout:(NSTimeInterval)inTimeout
{
timeOut_ = inTimeout;
}
- (void) cancel
{
canceled_ = YES;
}
- (void) download:(NSURL*)inNSURL
{
NSRunLoop * tRunLoop;
pool_ = [[NSAutoreleasePool alloc] init];
tRunLoop = [NSRunLoop currentRunLoop];
url_ = inNSURL;
downloadFinished_ = NO;
canceled_ = NO;
if ( timeOut_ > 0 )
{
NSLog(@"MyDownloadManager:download - start timer");
timeOutTimer_ = [NSTimer scheduledTimerWithTimeInterval:timeOut_
target:self selector:@selector(downloadTimeOut:) userInfo:nil
repeats:NO];
}
[inNSURL loadResourceDataNotifyingClient:self usingCache:NO];
[tRunLoop run]; // without this, URLResourceDidFinishLoading and
others are never called
// Any code below this line is never reached
// [pool_ release]; // never reached
}
- (void) stopThread
{
[pool_ release];
[NSThread exit];
}
//
// client_ should implement:
// downloadTimeOut, URL:resourceDataDidBecomeAvailable:,
URLResourceDidFinishLoading:, URLResourceDidCancelLoading: and
URL:resourceDidFailLoadingWithReason:
// if all 5 following functions (sorry: methods - oops: messages) are
implemented.
//
- (void) downloadTimeOut:(NSTimer*)aTimer
{
if ( !downloadFinished_ )
{
[client_ downloadTimeOut];
[self stopThread];
}
}
- (void)URL:(NSURL *)sender resourceDataDidBecomeAvailable:(NSData
*)newBytes
{
if ( canceled_ )
{
[self stopThread];
}
else
{
[client_ URL:url_ resourceDataDidBecomeAvailable:newBytes];
}
}
- (void)URLResourceDidFinishLoading:(NSURL *)sender
{
downloadFinished_ = YES;
[client_ URLResourceDidFinishLoading:url_];
[self stopThread];
}
- (void)URLResourceDidCancelLoading:(NSURL *)sender
{
downloadFinished_ = YES;
[client_ URLResourceDidCancelLoading:url_];
[self stopThread];
}
- (void)URL:(NSURL *)sender resourceDidFailLoadingWithReason:(NSString
*)reason
{
downloadFinished_ = YES;
[client_ URL:url_ resourceDidFailLoadingWithReason:reason];
[self stopThread];
}
@end
On the client side:
...
downloadmanager_ = [[MyDownloadManager alloc] init:(id)self];
...
[downloadmanager_ setTimeout:60]; // seconds
[NSThread detachNewThreadSelector:@selector(download:)
toTarget:downloadmanager_ withObject:tUrl_ ];
// instead of:
// [tUrl_ loadResourceDataNotifyingClient:self usingCache:NO];
...
[downloadmanager_ cancel]; // cancels downloading if it is in progress
...
[downloadmanager_ release];
Any better idea or comments are welcome!
Marc
On mercredi, octobre 31, 2001, at 10:41 , Steven W. Riggins wrote:
I am looking into this as well. I have not used Threads yet, but thats
my bet. Make a thread to load the URL, and let the main thread do the
UI/Waiting, then just kill the thread if it times out?
Hi!
I am using the loadResourceDataNotifyingClient message of NSURL.
This works fine but I don't know how to cancel this action.
If the user is connected via PPP and modem to the internet and has
automatic connection activated, and if for any reason the connection
does not work, the systems displays alert boxes asking for password or
whatever is needed. The user can cancel. But it look like that the
request remains pending and the system redisplays those alert boxes
again and again. Until I quit my application.
If the user is downloading a big file, or if for whatever reason the
downloading process takes time, it would be also nice for him to have
the possibility to cancel. What I do is to use a helper app for
downlod which I quit if the user cancels... Not very elegant!
Thanks for any ideas,
Marc
_______________________________________________
cocoa-dev mailing list
email@hidden
http://www.lists.apple.com/mailman/listinfo/cocoa-dev