在再次调用之前,如何等待方法完成?

时间:2015-01-22 13:37:52

标签: ios objective-c

我正在使用Parse的框架构建一个简单的消息传递应用程序。我有一个名为displayMessages的方法。每次手机接到推送时都会调用此方法。

但是,由于此消息在Parse数据库中正在工作,所以如果它已经在运行,我不想再次调用它。我想等到它完成然后再打电话。

我使用以下代码:

-(void)receivedPush
{

    [self displayMessages];

}

和:

-(void)displayMessages
{
 //code here
}

如果收到push被叫,我希望它等到displayMessages完成后再调用它。有人可以指出我正确的方向吗?

更新

我尝试使用NSOperationQueue方法并意识到虽然这对等待displayMessages起作用,但它不会导致所需的行为。

displayMessages我有:[PFObject deleteAllInBackground:toDelete];实际上,我需要等待完成才能再次致电displayMessages

6 个答案:

答案 0 :(得分:4)

创建NSOperationQueue并将maxConcurrentOperationCount设置为1.将数据访问方法实现为操作(可能是块类型操作)并将其提交到队列。 (我比gcd更喜欢这个,因为你可以取消或测试队列中已有的项目数。)

请注意,如果方法实际显示内容,则需要调度回主队列以进行UI工作。

答案 1 :(得分:3)

您可以使用NSOperationQueue maxConcurrentOperationCount设置为1

NSOperationQueue声明为您班级的iVar,在init方法中对其进行初始化并设置

[_opQueue setMaxConcurrentOperationCount:1];

然后当你收到推送时:

- (void)receivedPush {
    NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(displayMessages) object:nil];
    [_opQueue addOperation:op];
}

答案 2 :(得分:0)

最短和简单就是创建BOOL isExecuting并检查你是否可以根据它调用方法(在执行之前但在检查之后和执行之后更改值)

答案 3 :(得分:0)

这对于一个相当轻量级的解决方案来说如何:

@property (nonatomic, assign) BOOL needsToDisplayMessages;
@property (nonatomic, assign) BOOL displayingMessages;

然后

-(void)receivedPush
{
    if (!self.displayingMessages) {
        [self displayMessages];
    } else {
        self.needsToDisplayMessages = YES;
   }
}


-(void)displayMessages
 {
  self.needsToDisplayMessages = NO;
  self.displayingMessages = YES;
  //long-running code here

  self.displayingMessages = NO;
  if (self.needsToDisplayMessages) {
       [self displayMessages]
  } 

(忽略并发问题......根据其他几个答案,您可以在displayMessagesNSOperationQueue中使用GCD)

答案 4 :(得分:0)

根据您的新更新要求,您可以使用deleteAllInBackground:block:。根据{{​​3}}:

“异步删除所有对象集合,并在完成时执行该块。”

答案 5 :(得分:-1)

为什么不使用以下方式安排每个邮件处理:

-(void)receivedPush
{
  dispatch_async(dispatch_get_main_queue(), ^{
    /* Show the update on the display */
    NSLog(@"Handling new messages");
    NSArray *newMessages=<populate with new messages>;
    [handler displayMessages:newMessages];            
  });
}

这将排除您对每个集合的处理。一次只能运行一个displayMessages。