2011-08-09 55 views
1

我很难用键值观察手动触发属性更新。这里是一个人为的例子来说明我的问题:触发与KVO属性更新

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:事件?这种方法不能像我认为的那样工作吗?

回答

6

它不触发通知,因为你忘了相应

[self willChangeValueForKey:@"test"]; 

必须始终配对didChangeValueForKey:

+0

我不知道他们应该配对。这工作完美。谢谢。 – LandonSchropp

1

NSKeyValueObservingOptions

这些常数被传递到的addObserver:forKeyPath:选项:上下文:以及确定被返回传递给observeValueForKeyPath变化字典的一部分的值:ofObject:变化:上下文:. 如果不需要更改字典值,则可以传递0。

枚举{

NSKeyValueObservingOptionNew = 0×01,

NSKeyValueObservingOptionOld = 0×02,

NSKeyValueObservingOptionInitial = 0×04,

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"]; 
} 
+0

感谢您的回复。你所说的话非常有道理,但是随着改变,我仍然看到“改变了!”输出一次。 – LandonSchropp

相关问题