并发NSOperation以及如何设置isFinished和isExecuting?

时间:2015-01-26 16:11:56

标签: ios xcode nsoperation nsoperationqueue

我正在尝试使用NSOperations拆分我的程序流程。我正在使用Parse框架来创建一个简单的消息传递应用程序。我想显示一些消息,然后删除它们。除非删除操作已完成,否则不应调用显示消息,因此我想尝试使用NSQueue并向其添加displayMessages操作,然后添加deleteMessages操作(下面名为MyOperation)。我知道并发操作意味着它们只能以队列方式一个接一个地执行。下面是我删除方法的代码。有没有办法手动告诉它完成的操作,即设置isFinished或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仍在运行,这个也将完成。非常感谢这里的一些帮助!感谢


其他可能的解决方案:

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

            }


        });
    });



}

2 个答案:

答案 0 :(得分:1)

我建议您使用下面的dispatch_async;

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获取任务完成通知;设置队列时,请执行以下操作:

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

然后在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];
            }
        });
    });
}
}

答案 1 :(得分:0)

如果要在删除完成之前阻止当前线程,请使用deleteAll而不是deleteAllInBackground