objective c - NSNotification sent once, but is received multiple times -
i communicating between 2 classes nsnotificationcenter. problem although tap button once (and button fires off once) unintentionally producing increasing numbers of notifications 1 call nsnotificationcenter.
here better explanation of problem, code:
my 2 classes mainview class , menu class.
when view in mainview class tapped, launches view created , governed menu class. code called when mainview initialized:
menu=[[mymenu alloc] init]; uitapgesturerecognizer * tap=[[uitapgesturerecognizer alloc] initwithtarget:self action:@selector(ontapped:)]; [tap setnumberoftapsrequired:1]; [container addgesturerecognizer:tap]; [[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(onchangeitem:) name:@"itemchange" object:nil];
this gesture recognizer fires off method, in mainview class:
- (void) ontapped: (uigesturerecognizer*) recognizer { nslog(@"tap"); [menu displaymenu]; }
this how menu class initializes:
- (mymenu*) init { self=[super init]; uicollectionviewflowlayout * layout=[[uicollectionviewflowlayout alloc] init]; menuview=[[uicollectionview alloc] initwithframe:cgrectmake(0, 0, 200, 200) collectionviewlayout:layout]; [menuview setdatasource:self]; [menuview setdelegate:self]; [menuview registerclass:[uicollectionviewcell class] forcellwithreuseidentifier:@"cell"]; [menuview setautoresizessubviews:yes]; [menuview setautoresizingmask:uiviewautoresizingflexibleheight | uiviewautoresizingflexiblewidth]; [menuview setbackgroundcolor:[uicolor clearcolor]]; [menuview setindicatorstyle:uiscrollviewindicatorstylewhite]; return self; }
and displaymenu
method inside menu class:
- (void) displaymenu { [viewformenu addsubview:menuview]; }
the menu class has clearmenu
method:
- (void) clearmenu { [menuview removefromsuperview]; }
this code each cell in uicollectionview, contained within menu class:
- (uicollectionviewcell*) collectionview:(uicollectionview *)collectionview cellforitematindexpath:(nsindexpath *)indexpath { uicollectionviewcell * cell=[collectionview dequeuereusablecellwithreuseidentifier:@"cell" forindexpath:indexpath]; [cell settag:indexpath.row]; uitapgesturerecognizer * tap=[[uitapgesturerecognizer alloc] initwithtarget:self action:@selector(onbuttontapped:)]; [tap setnumberoftapsrequired:1]; [cell addgesturerecognizer:tap]; nslog(@"button tapped : %d",indexpath.row); return cell; }
this calls onbuttontapped:
method, within menu class:
- (void) onbuttontapped:(uigesturerecognizer*) recognizer { nsinteger buttontapped=[[recognizer view] tag]; [[nsnotificationcenter defaultcenter] postnotificationname:@"itemchange" object:nil userinfo:@{@"selected":@(buttontapped)}]; [self clearmenu]; }
this notification picked mainview class code:
[[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(onchangeitem:) name:@"itemchange" object:nil];
this calls onchangeitem:
method, inside mainview class:
- (void) onchangeitem: (nsnotification*) notification { nslog(@"change item %d",[[[notification userinfo] objectforkey:@"clock"] intvalue]); }
so that's code.
ok, here's problem: first time menu displays in log:
...[43023:11f03] tap ...[43023:11f03] button tapped : 1 ...[43023:11f03] change item 1
and fine, expect. second time around this:
...[43023:11f03] tap ...[43023:11f03] button tapped : 1 ...[43023:11f03] change item 1 ...[43023:11f03] change item 1
third time around this:
...[43023:11f03] tap ...[43023:11f03] button tapped : 1 ...[43023:11f03] change item 1 ...[43023:11f03] change item 1 ...[43023:11f03] change item 1 ...[43023:11f03] change item 1
and on. each successive tap on menu item doubles amount of notification calls.
to begin thought adding multiple views, , resulting in multiple button taps, , therefore multiple notifications calls.
however can see logs, not case. the buttons receiving 1 tap event - firing off 1 notification - receiving class gets sent multiple notifications.
can explain me?
sorry lengthy post!
well, assuming [[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(onchangeitem:) name:@"itemchange" object:nil];
being added more once.
i remove potential observer before adding observer, so:
[[nsnotificationcenter defaultcenter] removeobserver:self name:@"itemchange" object:nil]; [[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(onchangeitem:) name:@"itemchange" object:nil];
that way there ever 1 observer callback.
Comments
Post a Comment