ios学习--KVO模式关键函数

来源:互联网 发布:php点餐系统 编辑:程序博客网 时间:2024/04/28 17:36
将self添加为self.inProgressAdder的观察者,观察的属性为 isFinished,isExecuting


- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;

以上两个函数放在self这个的实现中

[self.inProgressAdder addObserver:self forKeyPath:@"isFinished"  options:0 context:&self->_formattedTotal];
[self.inProgressAdder addObserver:self forKeyPath:@"isExecuting" options:0 context:&self->_queue];

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if (context == &self->_formattedTotal) {
        AdderOperation *    op;

        // If the operation has finished, call -adderOperationDone: on the main thread to deal
        // with the results.

        // can be running on any thread
        assert([keyPath isEqual:@"isFinished"]);
        op = (AdderOperation *) object;
        assert([op isKindOfClass:[AdderOperation class]]);
        assert([op isFinished]);

        fprintf(stderr, "%c %3lu finished\n", CharForCurrentThread(), (unsigned long) op.sequenceNumber);
        if ([[NSUserDefaults standardUserDefaults] boolForKey:@"applyResultsFromThread"]) {
            [self adderOperationDone:op];
        } else {
            if ([[NSUserDefaults standardUserDefaults] boolForKey:@"allowStale"]) {
                [self performSelectorOnMainThread:@selector(adderOperationDoneWrong:) withObject:op waitUntilDone:NO];
            } else {
                [self performSelectorOnMainThread:@selector(adderOperationDone:)      withObject:op waitUntilDone:NO];
            }
        }
    } else if (context == &self->_queue) {
        AdderOperation *    op;
       
        // We observe -isExecuting purely for logging purposes.
       
        // can be running on any thread
        assert([keyPath isEqual:@"isExecuting"]);
        op = (AdderOperation *) object;
        assert([op isKindOfClass:[AdderOperation class]]);
        if ([op isExecuting]) {
            fprintf(stderr, "%c %3lu executing\n", CharForCurrentThread(), (unsigned long) op.sequenceNumber);
        } else {
            fprintf(stderr, "%c %3lu stopped\n", CharForCurrentThread(), (unsigned long) op.sequenceNumber);
        }
    } else if (context == &self->_inProgressAdder) {
   
        // If recalculating changes, reload the first section (kListAdderSectionIndexTotal)
        // which causes the activity indicator to come or go.
       
        assert([NSThread isMainThread]);
        assert([keyPath isEqual:@"recalculating"]);
        assert(object == self);
        [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:kListAdderSectionIndexTotal]] withRowAnimation:UITableViewRowAnimationNone];
    }
    if (NO) {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}