Запуск обновления свойства с KVO - PullRequest
1 голос
/ 09 августа 2011

Мне трудно вручную запустить обновление свойства с наблюдением значения ключа.Вот надуманный пример, иллюстрирующий мою проблему:

Bar.h

#import <Foundation/Foundation.h>

@interface Bar : NSObject
{
    NSString *test;
}

@property (nonatomic, retain) NSString *test;

-(void) updateTest1;
-(void) updateTest2;

@end

Bar.m

#import "Bar.h"

@implementation Bar

@synthesize test;

-(id) init
{
    if (self = [super init])
    {
        self.test = @"initial";
    }
    return self;
}

-(void) updateTest1
{
    self.test = @"updating 1";
}

-(void) updateTest2
{
    NSString *updateString = @"updating 2";
    [updateString retain];
    test = updateString;
    [self didChangeValueForKey:@"test"];
}

@end

Foo.h

#import <Foundation/Foundation.h>

@interface Foo : NSObject

@end

Foo.m

#import "Foo.h"

@implementation Foo

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"something changed!");
}

@end

main.m

#import <Foundation/Foundation.h>
#import "Foo.h"
#import "Bar.h"

int main (int argc, const char * argv[])
{

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    Bar *bar = [Bar new];
    Foo *foo = [Foo new];

    [bar addObserver:foo forKeyPath:@"test" options:0 context:nil];

    [bar updateTest1];
    [bar updateTest2];

    [pool drain];
    return 0;
}

Программа возвращает:

2011-08-09 03:57:52.630 Temp[5159:707] something changed!
Program ended with exit code: 0

Почему didChangeValueForKey: не вызывает у наблюдателя observeValueForKeyPath:ofObject:change:context:событие?Этот метод не работает так, как я думаю?

Ответы [ 2 ]

6 голосов
/ 09 августа 2011

Это не вызывает уведомление, потому что вы забыли соответствующий

[self willChangeValueForKey:@"test"];

, который всегда должен быть в паре с didChangeValueForKey:

1 голос
/ 09 августа 2011

NSKeyValueObservingOptions

Эти константы передаются в addObserver: forKeyPath: options: context: и определяют значения, которые возвращаются как часть словаря изменений, передаваемого в наблюдаемое значение ForKeyPath: ofObject: change: context :. Вы можете передать 0, если не требуется изменять значения словаря.

enum {

NSKeyValueObservingOptionNew = 0x01,

NSKeyValueObservingOptionOld = 0x02,

NSKeyValueObservingOptionInitial = 0x04,

NSKeyValueObservingOptionPrior = 0x08

}; typedef NSUInteger NSKeyValueObservingOptions;

попробуй вот так

[bar addObserver:foo forKeyPath:@"test" options:NSKeyValueObservingOptionNew context:nil];

изменить этот код

-(void) updateTest2
{
    NSString *updateString = @"updating 2";
    [updateString retain];
    test = updateString;
    [self didChangeValueForKey:@"test"];
}

до

-(void) updateTest2
{


    self.test = @"updating 2"//note here

    [self didChangeValueForKey:@"test"];
}
...