2014-07-26 17 views
26

Próbuję zrobić prosty przykład KVO, ale mam problemy.Prosty przykład KVO

To jest mój plik * .m:

#import "KVO_ViewController.h" 

@interface KVO_ViewController() 

@property NSUInteger number; 

@end 

@implementation KVO_ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 

    [self addObserver:self forKeyPath:@"number" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil]; 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

- (IBAction)incNumber:(id)sender 
{ 
    _number++; 
    NSLog(@"%d", _number); 
} 

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    NSLog(@"From KVO"); 

    if([keyPath isEqualToString:@"number"]) 
    { 
     id oldC = [change objectForKey:NSKeyValueChangeOldKey]; 
     id newC = [change objectForKey:NSKeyValueChangeNewKey]; 

     NSLog(@"%@ %@", oldC, newC); 
    } 
} 

@end 

Uwaga: Mam przycisk, który po kliknięciu będzie inkrementować właściwość number.
Chcę otrzymywać powiadomienia o zmianie właściwości number.

Kod nie działa i nie mogę go określić.

Odpowiedz

20

KVO współpracuje z setter i getter i incNumber masz bezpośredniego dostępu Ivar więc zamiast tego zastosowania self.number

- (IBAction)incNumber:(id)sender 
{ 
    self.number++; 
    NSLog(@"%d", self.number); 
} 
+1

'self.number ++ 'również działa. Za 10 minut przyjmuję twoją odpowiedź. – WebOrCode

+0

tak też będzie działać. – codester

+1

W całym moim czytaniu o KVO, nikt nie zadał sobie trudu, aby wspomnieć, że musisz ustawić właściwości w ten sposób, dopóki tego nie znalazłem. Dzięki. – inorganik

9

Zamiast:

_number++; 

Spróbuj:

[self willChangeValueForKey:@"number"]; 
_number++; 
[self didChangeValueForKey:@"number"]; 

lub jeszcze lepiej:

self.number++ 

I niech system zajmie się metodami willChangeValueForKey: i didChangeValueForKey:.

+4

co, jeśli obiekt nie znajduje się w tej samej klasie. Jest to obiekt w klasie singleton. Jak ubiegać się o to KVO. – Nishant

2
@interface TraineeLocationCell : UIView 
@property (strong, nonatomic) NSString *traineeAddress; 
@end 

@implementation 

// in textview delgate method i am setting traineeAddress string value 
- (void)textViewDidEndEditing:(UITextView *)textView 
{ 
    if (textView.text.length >0) 
    [self setValue:textView.text forKey:@"traineeAddress"]; 

} 

@end 

aw drugiej klasy, w których używam tej klasy

TraineeLocationCell *locationView;//create object here 
[locationView addObserver:self forKeyPath:@"traineeAddress" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];//observing the key in this class 

// Jest to metoda, która delegat dbać o zmianie wartości lub nie

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    if([keyPath isEqualToString:@"traineeAddress"]){ 
     if (!settingsValues.address) 
      settingsValues.address = [[NSMutableArray alloc]initWithObjects:[change valueForKey:@"new"], nil]; 

     else 
      [settingsValues.address replaceObjectAtIndex:0 withObject:[change valueForKey:@"new"]]; 
    } 
}