objective c - Key Value Observing context not work -


in objective-c, when using key-value observing, have bank class accountdomestic property , person property. person added observe accountdomestic property. have static void *bankcontext = & bankcontext in bank class context. however, after change accountdomestic property, old , new value not shown correctly due mismatch of context , bankcontext in -(void)observevalueforkeypath:(nsstring *)keypath ofobject:(id)object change:(nsdictionary<nsstring *,id> *)change context:(void *)contextmethod in person.

the code following, first bank class:

bank.h  #import <foundation/foundation.h> #import "person.h"  static void * const bankcontext = &bankcontext; @class person;  @interface bank : nsobject @property (nonatomic, strong) nsnumber* accountdomestic; @property (nonatomic, strong) person* person; -(instancetype)initwithperson:(person *)person; @end    bank.m  @implementation -(instancetype)initwithperson:(person *)person{     if(self = [super init]){         _person = person;         [self addobserver:_person                 forkeypath:nsstringfromselector(@selector(accountdomestic))                    options:nskeyvalueobservingoptionold|nskeyvalueobservingoptionnew                   context:bankcontext]; }     return self; }  -(void)dealloc{     [self removeobserver:_person forkeypath:nsstringfromselector(@selector(accountdomestic))]; }  @end 

then person class:

person.h  #import <foundation/foundation.h> #import "bank.h" @interface person : nsobject @end   person.m  #import "person.h" @implementation person  -(void)observevalueforkeypath:(nsstring *)keypath ofobject:(id)object change:(nsdictionary<nsstring *,id> *)change context:(void *)context{     nslog(@"context: %p",context);     nslog(@"bankcontext: %p",bankcontext);     if(context == bankcontext){         if([keypath isequaltostring:nsstringfromselector(@selector(accountdomestic))]){             nsstring *oldvalue = change[nskeyvaluechangeoldkey];             nsstring *newvalue = change[nskeyvaluechangenewkey];             nslog(@"--------------------------");             nslog(@"accountdomestic old value: %@", oldvalue);             nslog(@"accountdomestic new value: %@", newvalue);         }     } }  @end 

at last viewcontroller class

viewcontroller.h  #import <uikit/uikit.h> @interface viewcontroller : uiviewcontroller @end   viewcontroller.m  #import "viewcontroller.h" #import "bank.h" #import "person.h" @interface viewcontroller () @property (nonatomic, strong) bank *bank; @property (nonatomic, strong) person *person; @property (nonatomic, strong) nsnumber *delta; @end  @implementation viewcontroller  - (void)viewdidload {     [super viewdidload];     self.person = [[person alloc] init];     self.delta = @10;     self.bank = [[bank alloc] initwithperson:self.person]; }  - (ibaction)accountdomesticincreasebuttondidtouch:(id)sender {     self.bank.accountdomestic = self.delta;     int temp = [self.delta intvalue];     temp += 10;     self.delta = [nsnumber numberwithint:temp]; } @end 

after click button, new , old value of accountdomestic not shown. can see context , bankcontext value not equal picture shown below:

enter image description here

does have idea of that?

the reason there 2 bankcontexts. in bank.h, have

static void * const bankcontext = &bankcontext;

this file included in both bank.m , person.m, both files (compilation units) define pointer bankcontext, marked static generates no external linkage (so can have 2 same name).

the direct solution ensure there 1 bankcontext. in bank.h:

extern void * const bankcontext;

and in bank.m:

void * const bankcontext = &bankcontext;

more static , extern.

that said, think better restructure code isn’t necessary. setup of responsibilities makes me wary (one object telling become observer), , i’m surprised compiles correctly since there appear cyclic imports (bank.h , person.h import each other).


Comments

Popular posts from this blog

java - Run spring boot application error: Cannot instantiate interface org.springframework.context.ApplicationListener -

reactjs - React router and this.props.children - how to pass state to this.props.children -

Excel VBA "Microsoft Windows Common Controls 6.0 (SP6)" Location Changes -