39

NSNotificationCenter を使用して、NSDictionary フォームを UIView から UIViewController に渡そうとしています。ディクショナリは、通知が投稿された時点では正常に機能しますが、受信メソッドでは、ディクショナリ内のオブジェクトにアクセスできません。

辞書を作成して通知を投稿する方法は次のとおりです...

itemDetails = [[NSDictionary alloc] initWithObjectsAndKeys:@"Topic 1", @"HelpTopic", nil];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"HotSpotTouched" object:itemDetails];

UIViewController では、オブザーバーを設定しています...

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

テスト目的で、hotSpotMore は次のようになります...

- (void)hotSpotMore:(NSDictionary *)itemDetails{
      NSLog(@"%@", itemDetails);
      NSLog(@"%@", [itemDetails objectForKey:@"HelpTopic"]);    
}

最初の NSLog は正常に機能し、辞書の内容を表示します。2番目のログは次の例外をスローします...

 [NSConcreteNotification objectForKey:]: unrecognized selector sent to instance 0x712b130

渡された辞書のオブジェクトにアクセスできない理由がわかりません。

助けてくれてありがとう。

ジョン

4

3 に答える 3

111

最初のNSLogは、辞書の内容を表示して正常に機能します。2番目のログは次の例外をスローします...

プログラムはあなたをだまそうとします。あなたの辞書は通知の中にあるので、それはあなたの辞書のように見えます。例外から、オブジェクトが実際にはNSConcreteNotificationという名前のクラスからのものであることがわかります。
これは、notification-methodの引数が常にNSNotification-objectであるためです。これは機能します:

- (void)hotSpotMore:(NSNotification *)notification {
      NSLog(@"%@", notification.object);
      NSLog(@"%@", [notification.object objectForKey:@"HelpTopic"]);    
}

ヒントとして:オブジェクトは通常、通知を送信するオブジェクトです。NSDictionaryをuserInfoとして送信する必要があります。
次のようにすると、コードが改善されると思います。

NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center postNotificationName:@"HotSpotTouched" object:self userInfo:itemDetails];


- (void)hotSpotMore:(NSNotification *)notification {
      NSLog(@"%@", notification.userInfo);
      NSLog(@"%@", [notification.userInfo objectForKey:@"HelpTopic"]);    
}

オブジェクトパラメータは、通知を送信できるさまざまなオブジェクトを区別するために使用されます。
両方とも通知を送信できる2つの異なるHotSpotオブジェクトがあるとします。を設定するobjectaddObserver:selector:name:object:、オブジェクトごとに異なるオブザーバーを追加できます。オブジェクトパラメータとしてnilを使用すると、通知を送信したオブジェクトに関係なく、すべての通知を受信する必要があります。

例えば:

FancyHotSpot *hotSpotA;
FancyHotSpot *hotSpotB;

// notifications from hotSpotA should call hotSpotATouched:
[[NSNotificationCenter defaultCenter] addObserver:self 
       selector:@selector(hotSpotATouched:) name:@"HotSpotTouched" 
       object:hotSpotA]; // only notifications from hotSpotA will be received

// notifications from hotSpotB should call hotSpotBTouched:
[[NSNotificationCenter defaultCenter] addObserver:self 
       selector:@selector(hotSpotBTouched:) name:@"HotSpotTouched" 
       object:hotSpotB]; // only notifications from hotSpotB will be received

// notifications from all objects should call anyHotSpotTouched:
[[NSNotificationCenter defaultCenter] addObserver:self 
       selector:@selector(anyHotSpotTouched:) name:@"HotSpotTouched" 
       object:nil]; // nil == “any object”, so all notifications with the name “HotSpotTouched” will be received


- (void)hotSpotATouched:(NSNotification *)n {
    // only gets notification of hot spot A
}

- (void)hotSpotBTouched:(NSNotification *)n {
    // only gets notification of hot spot B
}

- (void)anyHotSpotTouched:(NSNotification *)n {
    // catches all notifications
}
于 2010-11-08T20:01:26.933 に答える
4

これは、辞書データを NSNotification で渡す最良の方法です。

投稿通知:

 [[NSNotificationCenter defaultCenter] postNotificationName:@"Put Your Notification Name" object:self userInfo:"Pass your dictionary name"];

通知を処理するオブザーバーを追加します。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mydictionaryData:)  name:@"Put Your Notification Name" object:nil];

Put Notification Handler メソッド。

- (void)mydictionaryData::(NSNotification*)notification{
   NSDictionary* userInfo = notification.userInfo;
   NSLog (@"Successfully received test notification! %@", userInfo);}

このソリューションがお役に立てば幸いです

于 2013-03-18T08:20:32.743 に答える
3

マティアスが話している方法と、あなたが使うべきだと私が思う方法は

postNotificationName:object:userInfo:

object は送信者で、userInfo は辞書です。

于 2012-02-02T20:46:51.980 に答える