Setting timeout on a delegate method in objective c
i need to set a NSTimer object to manually timeout a server call if it is taking more than 10 seconds (not supported in Restkit)
This is my code below. Essentially, my loader class will delegate the request with loadObjectsAtResourcePath
If it takes more than 10 seconds, I would like to call the same failure method that Restkit calls when it hits an error with the server (didFailWithError)
But i feel that i am doing it wrong, and furthermore, the failure method requires a object which is only initialized in the delegate class.
//CLASS FOR LOADING OBJECTS
-(void)getObjects{
RKObjectManager *sharedMan开发者_如何转开发ager = [RKObjectManager sharedManager];
// loads the object via delegate
[sharedManager loadObjectsAtResourcePath:self.resourcePath delegate:self];
//creates an error
NSError *error = [NSError errorWithDomain:@"world" code:200 userInfo:nil];
// Setting timeout here. goto failure
nTimer = [NSTimer scheduledTimerWithTimeInterval:10.0f target:self.delegate selector:@selector:(objectLoader:nil didFailWithError:error:) userInfo:nil repeats:NO];
}
// handles failure
- (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError*)error {
..
}
// handles success
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
..
}
What is the right way to do this?
It would be better to handle the timeout in a method other than the delegate callback. As you say, the delegate method requires objects that are created within the class. And you probably don't want to handle a "real error" and a timeout in exactly the same way, right? With a timeout you might, for example, want the option of trying again.
If you did want the timeout and failing with an error to do exactly the same thing, you can stil use another method for this:
-(void)getObjects{
RKObjectManager *sharedManager = [RKObjectManager sharedManager];
// loads the object via delegate
[sharedManager loadObjectsAtResourcePath:self.resourcePath delegate:self];
//creates an error
NSError *error = [NSError errorWithDomain:@"world" code:200 userInfo:nil];
// Setting timeout here. goto failure
nTimer = [NSTimer scheduledTimerWithTimeInterval:10.0f target:self selector:@selector(didTimeout) userInfo:nil repeats:NO];
}
- (void)didTimeout {
NSLog(@"Error");
}
// handles failure
- (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError*)error {
[self didTimeout];
}
// handles success
- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects {
//don't forget to invalidate the time or else you'll get errors even when successful
[nTimer invalidate];
}
You can of course extend this to be more flexible if necessary, but this seems to cover what you asked.
Not familiar with RestKit but the first thing I think of is that it would be far better to set the scheduled selector to call a verfication method rather than the did fail method, have the verification method check to see if a valid response has been received within the defined time and if it hasn't then cancel the request etc and call the fail.
Whilst I am not familiar with RestKit I am familiar with using NSURLRequests and I know it's possible to define a timeout when you issue the request to generate a timeout failure - don't know if that helps...
精彩评论