延迟调用类方法

时间:2013-11-26 08:24:14

标签: ios objective-c delay

我有一个只包含类方法的类。通常,我使用这些方法刷新我的应用程序的数据。
这样,例如,我希望TableViewController从常规提到的第一个类触发方法。
我还需要的是当我的TableViewController不再显示时停止这些调用的可能性。

我现在正在做的可能不是最好的事情:

//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];
    });
}

使用此问题有3个问题:

  • 一旦添加到主队列,我无法取消下一次刷新,就像解雇我的TableViewController时应该做的那样导致第二点
  • 因为任务已排队,如果我的TableViewController被解除,我将无法通话。
  • myTableViewController是一个通用类,因此我可以创建此类的新对象,并且这个对象将收到不合规的更新通知,并将导致崩溃。 (注意:它们不是同时是2 myTableViewController)

我应该如何处理这些限制并写一个“整齐的男女同校”:p

感谢您的帮助。

修改

通过@AdamG的链接,我创建了一个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

但是我无法取消它。这就是我正在做的事情:

-(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];
}

的确,当我的观点消失时,它仍然在控制台中写着“现在刷新”。

1 个答案:

答案 0 :(得分:2)

您应该使用NSOperations,这将允许您取消在后台运行的操作。

这里有一个很棒的教程:http://www.raywenderlich.com/19788/how-to-use-nsoperations-and-nsoperationqueues

它也更高效,并且可以防止您的应用因后台任务而滞后。

<强>更新

要取消,您必须在NSOperation中手动添加取消。您应该在可能希望取消操作的地方(可能在延迟之前和之后)添加此项。

if (self.isCancelled){
   // any cleanup you need to do
   return;
}