并发 NSOperation 以及如何设置 isFinished 和 isExecuting? [英] Concurrent NSOperation and how to set isFinished and isExecuting?

查看:51
本文介绍了并发 NSOperation 以及如何设置 isFinished 和 isExecuting?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 NSOperations 拆分我的程序流.我正在使用 Parse 框架来制作一个简单的消息应用程序.我想显示一些消息,然后删除它们.除非删除操作完成,否则不应调用显示消息,因此我想尝试使用 NSQueue 并向其添加 displayMessages 操作,然后添加 deleteMessages 操作(下面命名为 MyOperation ).我知道并发操作意味着它们只会以队列方式一个接一个地执行.下面是我的删除方法代码.有没有办法手动告诉操作它已完成,即设置 isFinished 或 isExecuting??

I am trying to split up my programs flow using NSOperations. I am using the Parse framework to make a simple messaging app. I want to display some messages and then delete them. The display messages shouldn't be called unless the delete operations is finished so I want to try using an NSQueue and add a displayMessages operation to it and then a deleteMessages operation (named MyOperation below). I understand that concurrent operations means they will only execute one after another in a queue fashion. Below is my code for the delete method. Is there a way to manually tell the operation it is finished i.e. setting isFinished or isExecuting??

// MyOperation.h
@interface MyOperation : NSOperation {
@property (strong, nonatomic) NSMutableArray *toDelete;
}
@end
And the implementation:

// MyOperation.m
@implementation MyOperation


- (id)initWithArray:(NSMutableArray *)array
{
    self = [super init];
    if (self == nil)
        return nil;

    _toDelete=array;

}

- (void)main {
    if ([self isCancelled]) {
        NSLog(@"** operation cancelled **");
    }



//how do I get main to finish execution ONLY after deleteAllInBackground has finished? 


[PFObject deleteAllInBackground:self.toDelete];

    if ([self isCancelled]) {
        NSLog(@"** operation cancelled **");
    }


    NSLog(@"Operation finished");
}


@end

现在上面的代码不能解决我的问题.它会将操作排队,但即使 deleteAllInBackground 仍在运行,这个操作也会完成.真的很感激这里的一些帮助!谢谢

right now this code above won't solve my problem. It will queue up the ops but this one will finish even though the deleteAllInBackground is still running. Would really appreciate some help here! thanks

其他可能的解决方案:

-(void)receivedMessage
{
    NSLog(@"push!");
    dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
        [self displayMessages];
        dispatch_async(dispatch_get_main_queue(), ^(void){
            if([self.toDelete count]>0) {
                [PFObject deleteAllInBackground:self.toDelete];

            }


        });
    });



}

推荐答案

我建议你像下面这样使用 dispatch_async;

I would suggest you to use dispatch_async like below;

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
    dispatch_async(dispatch_get_main_queue(), ^(void){
        // Display messages
    });
    // Delete messages here
});

如果你必须使用 NSOperationQueue 那么我建议你使用 KVO 来获取任务完成的通知;设置队列时,请执行以下操作:

If you have to use NSOperationQueue then I would suggest you to use KVO to get notification for task completion; When you setup your queue, do this:

[self.deleteQueue addObserver:self forKeyPath:@"delete-operations" options:0 context:NULL];

然后在您的 observeValueForKeyPath 中执行此操作:

Then do this in your observeValueForKeyPath:

- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
                     change:(NSDictionary *)change context:(void *)context {
    if (object == self.deleteQueue && [keyPath isEqualToString:@"delete-operations"]) {
        if ([self.queue.operations count] == 0) {
            // Delete operation done
            // Display messages here
        }
    } else {
        [super observeValueForKeyPath:keyPath ofObject:object 
                           change:change context:context];
     }
}

-(void)receivedMessage {
@synchronized(self) {
    NSLog(@"push!");
    dispatch_async(dispatch_get_main_queue(), ^(void) {
        [self displayMessages];
        dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
            if([self.toDelete count]>0) {
                // this deletion doesn't matter if background or on main thread as it's already in background queue
                [PFObject deleteAllInBackground:self.toDelete];
            }
        });
    });
}
}

这篇关于并发 NSOperation 以及如何设置 isFinished 和 isExecuting?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆