Concurrent NSOperation 以及如何设置 isFinished 和 isExecuting?
Concurrent NSOperation and how to set isFinished and isExecuting?
我正在尝试使用 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];
}
});
});
}
我建议您像下面那样使用 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];
}
});
});
}
}
如果要阻塞当前线程直到删除完成,请使用 deleteAll
而不是 deleteAllInBackground
。
我正在尝试使用 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];
}
});
});
}
我建议您像下面那样使用 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];
}
});
});
}
}
如果要阻塞当前线程直到删除完成,请使用 deleteAll
而不是 deleteAllInBackground
。