如何使用NSOperationQueue创建2个操作

时间:2014-10-15 17:21:29

标签: ios

我想创建两个同时运行的操作。一个人不断创建一个对象,并以15毫秒的间隔将其添加到队列中。另一个操作以10毫秒的间隔连续从队列中删除第一个项目。

- (void)viewDidLoad {
    [super viewDidLoad];

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;

    _arrInformations = [[NSMutableArray alloc] init];

    queue = [NSOperationQueue new];

    // start continuous processing
    [NSTimer scheduledTimerWithTimeInterval:0.15
                                     target:self
                                   selector:@selector(addNewInformation)
                                   userInfo:nil
                                    repeats:YES];

    [NSTimer scheduledTimerWithTimeInterval:0.1
                                     target:self
                                   selector:@selector(removeInformation)
                                   userInfo:nil
                                    repeats:YES];
}

-(void)addNewInformation {
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(addDataWithOperation) object:nil];
    /* Add the operation to the queue */
    [queue addOperation:operation];

}

- (void)removeInformation {
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(removeDataWithOperation) object:nil];
    /* Add the operation to the queue */
    [queue addOperation:operation];
    [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];
}

- (void) addDataWithOperation {
    NSLog(@"Add data");
    [_arrInformations addObject:@"Informations"];
}

- (void) removeDataWithOperation {
    if (_arrInformations.count) {
        [_arrInformations removeLastObject];
        [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];
    }
}

非常感谢!

2 个答案:

答案 0 :(得分:0)

我认为您不需要使用NSOperationQueue来实现此功能。 Grand Central Dispatch和Blocks应该为您提供所需的功能。

 - (void)viewDidLoad {
    [super viewDidLoad];

    _arrInformations = [[NSMutableArray alloc] init];
   _shouldContinue = YES; // set this to NO on viewWillDisappear to stop the dispatching
   [self addNewInformation];
}

-(void)addNewInformation {
    [_arrInformations addObject:@"Informations"];
    [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
if (_shouldContinue)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.15 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self removeInformation];
        });
}

- (void)removeInformation {
    [_arrInformations removeObject:@"Informations"];
    [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
if (_shouldContinue)
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self addInformation];
        });
}

您应该注意,每隔10-15毫秒调用-reloadData对iOS性能非常征税。您应该将NSNotificationCenterKVO视为响应数据更改的替代方法,而不是像这样在循环中导致它们。

答案 1 :(得分:0)

确实我也不会使用NSOperationQueue,而只是使用NSTimer几个:

NSTimer *producer = [NSTimer timerWithTimeInterval:0.001 target:self selector:@selector(produce:) userInfo:nil repeats:YES];
NSTimer *consumer = [NSTimer timerWithTimeInterval:0.001 target:self selector:@selector(consume:) userInfo:nil repeats:YES];

[[NSRunLoop mainRunLoop] addTimer:producer forMode:NSRunLoopCommonModes];
[[NSRunLoop mainRunLoop] addTimer:consumer forMode:NSRunLoopCommonModes];

然后代码中的其他地方:

- (void) produce:(id)sender
{
    //Produce your stuff here
}

- (void) consume:(id)sender
{
    //Consume your stuff here
}

或更短的形式:

NSTimer *producer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(produce:) userInfo:nil repeats:YES];
NSTimer *consumer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(consume:) userInfo:nil repeats:YES];

我将定时器分配给变量,因为我假设你想在某个时候停止定时器,你可以通过向实例发送invalidate消息来实现。