简体   繁体   English

延迟调用类方法

[英]Delay a call to a class method

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. 这样,例如,我希望TableViewController从常规提到的第一个类触发方法。
What I also need is the possibility to stop these calls when my TableViewController is not shown anymore. 我还需要的是当我的TableViewController不再显示时停止这些调用的可能性。

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 : 使用此问题有3个问题:

  • Once added to main queue, I can't cancel the next refresh, like I should do when dismissing my TableViewController and that leads to second point 一旦添加到主队列,我无法取消下一次刷新,就像解雇我的TableViewController时应该做的那样导致第二点
  • Because the task is queued, if my TableViewController is dismissed, I will have a useless call. 因为任务排队,如果我的TableViewController被解雇,我将进行无用的调用。
  • myTableViewController is a generic class, so I can create a new object of this class and this one will receive a non-compliant update notification, and will lead to a crash. myTableViewController是一个泛型类,所以我可以创建这个类的新对象,这个对象将收到一个不合规的更新通知,并将导致崩溃。 (note : their is not 2 myTableViewController at a same time) (注意:它们不是同时是2个myTableViewController)

How should I deal with these constraints and write a "neat coed" :p 我应该如何处理这些限制并写一个“整齐的男女同校”:p

Thanks for your help. 谢谢你的帮助。

EDIT 编辑

With the link of @AdamG, I've created a NSOperation : 通过@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

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. 实际上,当我的视图消失时,它仍然在控制台中写入“Now Refresh”。

You should be using NSOperations, which will allow you to cancel your operation that is running in the background. 您应该使用NSOperations,这将允许您取消在后台运行的操作。

There is a great tutorial here: http://www.raywenderlich.com/19788/how-to-use-nsoperations-and-nsoperationqueues . 这里有一个很棒的教程: 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 UPDATE

To cancel you have to manually add a cancellation in the NSOperation. 要取消,您必须在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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM