English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Sommario e differenze tra KVC, KVO, Notification e delegate in iOS

Sommario e differenze tra KVC, KVO, Notification e delegate in iOS

 1、KVC, che significa NSKeyValueCoding, un Protocolo informale, che fornisce un meccanismo per accedere indirettamente alle proprietà degli oggetti. Invece di accedere attraverso chiamate di Setter, Getter. KVO è una delle tecnologie chiave basate su KVC.

Demo:

@interface myPerson : NSObject
{  
    NSString*_name;  
    int   _age;  
    int   _height;  
    int   _weight;
}
@interface testViewController :UIViewController 
@property (nonatomic, retain) myPerson*testPerson; 
@end
- (void)testKVC;
{  
testPerson = [[myPerson alloc] init];    
 NSLog(@"testPerson's init height =%@", [testPerson valueForKey:@"height"]);  
[testPerson setValue:[NSNumber numberWithInt:168] forKey:@"height"]; NSLog(@"testPerson的高度 = %@
}

第一段代码定义了一个myPerson类,这个类有一个_height属性,但没有提供任何getter/setter访问方法。同时在testViewController这个类中有一个myPerson对象指针。

       当myPerson实例化后,常规来说无法访问这个对象的高度属性,但通过KVC我们做到了,代码就是testKVC这个函数。

       运行后打印的值就是:

2015-3-13 11:16:21.970 test[408:c07] testPerson的初始高度 = 0

2015-3-13 11:16:21.971 test[408:c07] testPerson的高度 = 168

    这就说明确实读写了_height属性。

    KVC的常用方法:

- (id)valueForKey:(NSString *)key; -(void)setValue:(id)value forKey:(NSString *)key;

valueForKey方法根据key的值读取对象的属性,setValue:forKey:是根据key的值来设置对象的属性。

注意:

(1) key的值必须正确,如果拼写错误,会出现异常

(2) 当key的值没有定义时,会调用valueForUndefinedKey:这个方法,如果你自己实现了这个方法,key的值出错就会调用到这里

(3) 因为类key反复嵌套,所以有一个keyPath的概念,keyPath就是用.号将一个一个key链接起来,这样就可以根据这个路径进行访问

(4) NSArray和NSSet等都支持KVC

2、KVO代表KeyValue Observe,中文是键值观察。这是一种典型的观察者模式,当键值发生变化时,观察者会收到通知。iOS中有一个Notification机制,也可以获得通知,但这个机制需要一个Center,相比之下KVO更加简洁直接。

      L'uso di KVO è molto semplice, è solo un passo di 3.

      1. Registra l'oggetto e l'attributo da osservare addObserver:forKeyPath:options:context:
      2. Implementa il metodo observeValueForKeyPath:ofObject:change:context:, che viene chiamato automaticamente quando l'attributo osservato cambia
      3. Annulla l'iscrizione all'osservazione removeObserver:forKeyPath:context:

Demo:

@interface myPerson : NSObject 
{ 
  NSString *_name; 
  int   _age; 
  int   _height; 
  int   _weight; 
} 
@end 
@interface testViewController : UIViewController 
@property (nonatomic, retain) myPerson *testPerson; 
- (IBAction)onBtnTest:(id)sender; 
@end 
- (void)testKVO 
{ 
  testPerson = [[myPerson alloc] init]; 
  [testPerson addObserver:self forKeyPath:@"height" options:NSKeyValueObservingOptionNew context:nil]; 
} 
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
  if ([keyPath isEqualToString:@"height"]) { 
    NSLog(@"Altezza è cambiata! nuovo=%@", [change valueForKey:NSKeyValueChangeNewKey]); 
  } else { 
    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 
  } 
} 
- (IBAction)onBtnTest:(id)sender {}} 
  int h = [[testPerson valueForKey:@"height"] intValue];   
  [testPerson setValue:[NSNumber numberWithInt:h+1] forKey:@"height"]; 
  NSLog(@"person height=%@", [testPerson valueForKey:@"height"]); 
} 
- (void)dealloc 
{ 
  [testPerson removeObserver:self forKeyPath:@"height" context:nil]; 
  [super dealloc]; 
} 

The first piece of code declares the myPerson class, which has a _height property. In testViewController, there is a pointer to the testPerson object.

      In the testKVO method, we registered the observation of the height property of the testPerson object, so that a notification will be received when the height property of testPerson changes. In this method, the NSKeyValueObservingOptionNew parameter is also required to pass the new value in the dictionary.

      The observeValueForKeyPath:ofObject:change:context: method has been overridden, and the change in this method's NSDictionary object contains the corresponding values.

      It should be emphasized that the callback of KVO must be called, and the property must be modified through the method of KVC. If the property is modified by calling other methods of the class, the observer will not receive a notification.

3. Usage of NSNotification can be seen at http://blog.csdn.net/eduora_meimei/article/details/44198909

Differences:

Advantages of delegate:

     1. Very strict syntax. All events that will be heard must be clearly defined in the delegate protocol.

     2. If a method of the delegate is not implemented, there will be compilation warnings or errors.

     3. The protocol must be defined within the scope of the controller.

      4. Nei controlli di un'applicazione, il flusso di controllo è tracciabile e riconoscibile;

     5. In un controller è possibile definire più protocolli diversi, ciascuno con diversi delegates;

     6. Non è richiesto alcun oggetto terzo per mantenere/monitorare il processo di comunicazione;

     7. Può ricevere il valore di ritorno del metodo del protocollo chiamato. Questo significa che il delegate può fornire informazioni di feedback al controller;

      Svantaggi :

     1. È necessario definire molto codice: 1. definizione del protocollo; 2. attributo delegate del controller; 3. implementazione dei metodi delegate nel delegate stesso;

     2. Quando si liberano gli oggetti proxy, è necessario cambiare con attenzione il delegate in nil. Se il cambio non avviene con successo, la chiamata al metodo di liberazione dell'oggetto causerà un crash di memoria;

     3. In un controller ci sono più oggetti delegate, e i delegate seguono lo stesso protocollo, ma è difficile comunicare lo stesso evento a più oggetti, anche se è possibile;

Vantaggi di notification :

       1. Non è necessario scrivere molto codice, è abbastanza semplice da implementare;

       2. Per un avviso emesso, più oggetti possono reagire, ovvero realizzare un modello 1-a-molti in modo semplice;

       3. Il controller può passare l'oggetto context (dictionary), che contiene informazioni personalizzate sullo invio dell'avviso;

       Svantaggi :

       1. Durante la fase di compilazione, non si verifica se l'avviso può essere gestito correttamente dall'osservatore;

       2. Quando si liberano gli oggetti registrati, è necessario annullare la registrazione nel centro di notifiche;

       3. Durante il debug, è difficile tracciare le operazioni e i processi di controllo applicati;

       4. È necessario utilizzare un terzo partito per gestire il legame tra l'oggetto controller e l'oggetto osservatore;

       5. Controller e osservatori devono sapere in anticipo il nome dell'avviso e le chiavi di UserInfodictionary. Se queste non sono definite nell'area di lavoro, si verificherà una situazione di disallineamento;

       6. Dopo che l'avviso è stato emesso, il controller non può ottenere alcuna informazione di feedback dagli osservatori;

Vantaggi di KVO :

        1. Fornisce un metodo semplice per sincronizzare due oggetti. Ad esempio: la sincronizzazione tra model e view;

        2. Può rispondere alle modifiche di stato degli oggetti non creati da noi, ossia degli oggetti interni, senza modificare l'implementazione dell'oggetto interno (oggetto SKD),;

        3. Fornisce i valori più recenti e precedenti delle proprietà osservate;

        4. Osservare le proprietà utilizzando key paths, quindi è possibile osservare anche gli oggetti annidati;

        5. E' stata completata l'astrazione dell'oggetto osservato, poiché non è necessario alcun codice aggiuntivo per permettere che gli osservati possano essere osservati;

       Svantaggi :

        1. Le proprietà che osserviamo devono essere definite utilizzando strings. Pertanto, non si verificheranno avvisi né controlli nel compilatore;

        2. La ristrutturazione delle proprietà farà sì che il nostro codice di osservazione non sia più disponibile;

        3. Le espressioni "IF" complesse richiedono che l'oggetto stia osservando più valori. Questo perché tutti i codici di osservazione si riferiscono a un metodo;

        4. Non è necessario rimuovere l'osservatore quando si rilascia.

1. L'efficienza è sicuramente maggiore con i delegate rispetto alle Notification.

I metodi delegate sono più diretti rispetto alle notification, il loro tratto distintivo più tipico è che i metodi delegate spesso richiedono di prestare attenzione al valore di ritorno, ossia al risultato del metodo delegate. Ad esempio, -windowShouldClose: richiede di preoccuparsi del fatto che il valore sia yes o no. Ecco perché i metodi delegate spesso contengono la parola should, che significa che se mi fai il mio delegate, ti chiederò se vuoi chiudere la finestra e tu dovrai darmi una risposta, in base alla quale deciderò come procedere. Al contrario, la caratteristica principale delle notification è che non si preoccupano dell'atteggiamento del destinatario, emetto l'avviso e non mi preoccupo di te o del risultato. Quindi le notification spesso usano il vocabolo did, come NSWindowDidResizeNotification, quindi quando l'oggetto NSWindow emette questa notification, non fa altro che procedere senza aspettare la reazione del destinatario.

2) Differenze tra KVO e Notification:

Come delegate, anche KVO e Notification hanno il ruolo di comunicazione tra classi, diversamente dai delegate, 1) entrambi sono responsabili di emettere notifiche, non si occupano di altro, quindi non hanno valore di ritorno; 2) delegate sono uno a uno, mentre questi possono essere uno a molti. Entrambi hanno le loro caratteristiche specifiche.

Grazie per aver letto, spero di essere stato d'aiuto, grazie per il supporto al nostro sito!

Ti potrebbe interessare