2013-08-07 6 views
8

NSNotificationCenterで2つのクラス間で通信しています。私の問題は、一度ボタンをタップしても(そのボタンは1回だけ消えます)、私は意図的にNSNotificationCenterへの1回の呼び出しから増加する数の通知を生成していることです。ここでNSNotificationは1回送信されましたが、複数回受信されました

は、コードの問題をよりよく説明、次のとおりです。


私の2つのクラスがMAINVIEWクラスとメニュークラスです。

MAINVIEWクラスのビューをタップする

は、それがメニュークラスによって作成され、支配ビューを起動します。このコードは、MAINVIEWが初期化されるときに呼び出されます。

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]; 

MAINVIEWクラスでこのメソッドオフこのジェスチャー認識部火災は、:

- (void) onTapped: (UIGestureRecognizer*) recognizer { 
    NSLog(@"tap"); 
    [menu displayMenu]; 
} 

これはどのようにメニュークラスです初期化:

- (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; 
} 

このメニュークラス内部displayMenu方法であって、メニュークラスもclearMenu方法を有する

- (void) displayMenu { 
    [viewForMenu addSubview:menuView]; 
} 

- (void) clearMenu { 
    [menuView removeFromSuperview]; 
} 

これは内に含まれ、UICollectionViewの各セルのためのコードであります私のメニュークラス:

- (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; 
} 

これがまた私のメニュークラス内で、onButtonTapped:メソッドを呼び出します。この通知は、このコードで私のMAINVIEWクラスによってピックアップされ

- (void) onButtonTapped:(UIGestureRecognizer*) recognizer { 
    NSInteger buttonTapped=[[recognizer view] tag]; 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"ItemChange" object:nil userInfo:@{@"selected":@(buttonTapped)}]; 
[self clearMenu]; 
} 

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onChangeItem:) name:@"ItemChange" object:nil]; 

これはonChangeItem:メソッドを呼び出します、内に私のmainViewクラス:

- (void) onChangeItem: (NSNotification*) notification { 
    NSLog(@"change item to %d",[[[notification userInfo] objectForKey:@"clock"] intValue]); 
} 

これがコードです。


OK、ここで問題があります:メニューが表示され、私は私のログにこれを取得する最初の時間:

...[43023:11f03] tap 
...[43023:11f03] button tapped : 1 
...[43023:11f03] change item to 1 

そして、これは結構です、これは私が期待するものです。私はこの取得の周りしかし二回目:周り

...[43023:11f03] tap 
...[43023:11f03] button tapped : 1 
...[43023:11f03] change item to 1 
...[43023:11f03] change item to 1 

3回目は、私はこれを取得:

...[43023:11f03] tap 
...[43023:11f03] button tapped : 1 
...[43023:11f03] change item to 1 
...[43023:11f03] change item to 1 
...[43023:11f03] change item to 1 
...[43023:11f03] change item to 1 

のように。メニュー項目の各連続したタップは、通知呼び出しの量を2倍にします。私は複数のビューを追加するため、複数のボタンのタップで、その結果、したがって、複数の通知呼び出したと思って


を開始します。

私のログからわかるように、これは当てはまりません。 ボタンは1タップイベントのみを受信して​​います - これは1通知のみを発していますが、受信クラスは複数の通知を送信します。

誰でもこのことを私に説明できますか?

長すぎる投稿を申し訳ありません!

+0

ここで、あなたは '[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onChangeItem :) name:@" ItemChange "object:nil];'を呼び出してそれを削除しますか?あなたの 'onChangeItem:'メソッドは 'NSLog(@"%p "、self);を監視している' self'のメモリアドレスを表示し、コンソールに表示されているものを表示します。 – 0x8badf00d

+0

** mainView **が初期化されたときに呼び出されます。それは一度だけ呼び出されます。 – Jimmery

+0

'onChangeItem:'メソッドに 'NSLog(@"%p "、self);を追加して、コンソールに表示された内容を表示できます – 0x8badf00d

答えて

28

まあ、私は[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onChangeItem:) name:@"ItemChange" object:nil];が複数回追加されていると仮定しています。

私はそうのように、オブザーバーを追加する前に、潜在的な観測を削除したい:

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"ItemChange" object:nil]; 
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onChangeItem:) name:@"ItemChange" object:nil]; 

史上唯一のオブザーバーコールバックがあるでしょうその方法。

+0

これは機能しませんでしたが、私は全く同じ結果を得ました。 – Jimmery

+0

@Jimmery "addObserver:"のグローバル検索を行う場合、それぞれの上に "removeObserver:"がありますか? – CodeReaper

+0

ああ。 OK。私はばかだ、あなたのコードを間違った場所に置く。それは私のバグを修正する適切な場所にあるので今!本当にありがとうございました:)私はあなたに偽のインターネットポイント以上のものを提供できることを願っています! – Jimmery

関連する問題