Reputation: 2818
I have a class which contains only class methods. Typically, I use these methods to refresh data for my app.
This way, for example, I want a TableViewController to trigged methods from the first class mentioned regularly.
What I also need is the possibility to stop these calls when my TableViewController is not shown anymore.
What I'm doing now is probably not the best thing to do :
//myNetworkingClass.h
+(void)methods1:(type*)param1;
---
//myNetworkingClass.m
+(void)methods1:(type*)param1
{
//asynchronous tasks
[[NSNotificationCenter defaultCenter] postNotificationName:@"updateComplete" object:responseObject];
}
//myTableViewController.m
- (void)viewDidLoad
{
//initialization
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateReceived:) name:@"updateComplete" object:nil];
[myNetworkingClass methods1:param];
}
-(void)updateReceived:(NSNotification*)notification
{
//some task, especially update datasource
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 10* NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[myNetworkingClass methods1:param];
});
}
There is 3 problems using this :
How should I deal with these constraints and write a "neat coed" :p
Thanks for your help.
EDIT
With the link of @AdamG, I've created a NSOperation :
@interface OperationRefresh : NSOperation
-(id)initWithArray:(NSArray *)array andDelay:(int)refreshTime;
@end
@implementation OperationRefresh
{
NSArray *paramA;
int delay;
}
-(id)initWithArray:(NSArray *)array andDelay:(int)refreshTime
{
self = [super init];
paramA = array;
delay = refreshTime;
return self;
}
-(void)main
{
@autoreleasepool {
NSLog(@"sleeping...");
[NSThread sleepForTimeInterval:delay];
NSLog(@"Now Refresh");
[myNetworkingClass methods1:paramA];
}
}
@end
But I'm not able to cancel it. Here is what I'm doing :
-(void)updateReceived:(NSNotification*)notification
{
//some task, especially update datasource
refreshOperation = [[OperationRefresh alloc] initWithArray:param andDelay:10];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
[refreshOperation start];
});
}
-(void)viewWillDisappear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[refreshOperation cancel];
}
Indeed, when my view disappears, it still writing "Now Refresh" in the console.
Upvotes: 0
Views: 191
Reputation: 3718
You should be using NSOperations, which will allow you to cancel your operation that is running in the background.
There is a great tutorial here: http://www.raywenderlich.com/19788/how-to-use-nsoperations-and-nsoperationqueues.
It's also much more efficient and will keep your app from lagging due to background tasks.
UPDATE
To cancel you have to manually add a cancellation in the NSOperation. You should add this wherever you might want the operation to be canceled (probably before and after the delay).
if (self.isCancelled){
// any cleanup you need to do
return;
}
Upvotes: 2