2015-04-24 16 views
6

pierwszy obraz używa self.name do zmiany, a drugi obraz za pomocą _name do zmiany.it powinien być taki sam wynik, ale drugi nic nie daje. Dlaczego?Różnica między self.variable i _variable, o KVO

enter image description here

enter image description here

oto kod

#import "ViewController.h" 

@interface kvo : NSObject 

@property (nonatomic,strong) NSString *name; 

@end 

@implementation kvo 

- (void)change 
{ 
    _name = @"b"; 
} 

@end 

@interface ViewController() 

@property (nonatomic, strong) kvo *a1; 

@end 

@implementation ViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.a1 = [[kvo alloc] init]; 
    _a1.name = @"a"; 
    [self.a1 addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew context:nil]; 
    [_a1 change]; 
} 

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

różnica jest self.name i _name w metodzie zmiany

Edit: to nie to samo pytanie, „Co to jest różnica między _variable & self.vari w stanie w Objective-C? [duplicate] ", wiem, że chodzi o metodę gettera i metodę setera, a moje pytanie brzmi, dlaczego metoda setera wywołuje KVO, a _name = @"b" nie wywołuje KVO.

+1

Proszę zaksięgować kod jako tekst, a nie zrzut ekranu xcode. Tekst jest łatwiejszy do wycinania/wklejania i w inny sposób można z nim pracować. – seand

+0

Arun, myślę, że to kolejne pytanie. –

+0

używając '_name' omijasz kvo – user2829759

Odpowiedz

5

Otrzymasz powiadomienie KVO tylko podczas uzyskiwania dostępu instancja zmiennej poprzez nieruchomości. bezpośrednie ustawienie zmiennej instancji nie będzie wywoływał KVO powiadomienie.

Oto pierwszy przypadek, ustawiasz nazwę przez

self.name = @"b"; 

W rzeczywistości będzie to wywołać metodę właściwość setter setName: który wewnętrznie wysyła powiadomienia KVO didChangeValueForKey. Właściwie notyfikacje są wystrzeliwane przez powołanie setter ..

W drugim przypadku

Jesteś bezpośrednio ustawiając zmienną instancji, bez metody nieruchomość seter. Tak więc powiadomienie KVO nie zostanie zwolnione.

Jeśli chcesz możesz odpalić zawiadomienia przez siebie

[self willChangeValueForKey:@"name"]; 

_name = @"b"; 

[self didChangeValueForKey:@"name"]; 

ale nie sądzę, że wymaga, ustawić zmienną przy użyciu właściwości. To wszystko zrobi dla ciebie.
Przeczytaj więcej o KVO notification

0

aby otrzymać klucz-wartość obserwacji informację o nieruchomości, potrzebne są trzy rzeczy:

Krok 1: Obserwowany klasa musi być klucz-wartość obserwując zgodny dla nieruchomości którą chcesz obserwować.

Krok 2: Musisz zarejestrować obiekt obserwacyjny z obserwowanym obiektem, używając metody addObserver:forKeyPath:options:context:.

Krok 3: Klasa obserwująca musi wdrożyć observeValueForKeyPath:ofObject:change:context:.

Apple Developer