I am trying to pass an NSDictionary form a UIView to a UIViewController using NSNotificationCenter. The dictionary works fine at the time the notification is posted, but in the receiving method I am unable to access any of the objects in the dictionary.
我试图通过NSDictionary从UIView传递给UIViewController使用NSNotificationCenter。该字典在发布通知时运行良好,但在接收方法中,我无法访问字典中的任何对象。
Here is how I am creating the dictionary and posting the notification...
下面是我如何创建字典并发布通知…
itemDetails = [[NSDictionary alloc] initWithObjectsAndKeys:@"Topic 1", @"HelpTopic", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"HotSpotTouched" object:itemDetails];
In the UIViewController I am setting the observer...
在UIViewController中,我设置观察者。
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(hotSpotMore:)
name:@"HotSpotTouched"
object:nil];
For testing purposes hotSpotMore looks like this...
出于测试目的hotSpotMore这个样子……
- (void)hotSpotMore:(NSDictionary *)itemDetails{
NSLog(@"%@", itemDetails);
NSLog(@"%@", [itemDetails objectForKey:@"HelpTopic"]);
}
The first NSLog works fine displaying the contents of the dictionary. The second log throws the following exception...
第一个NSLog可以很好地显示字典的内容。第二个日志抛出以下异常…
[NSConcreteNotification objectForKey:]: unrecognized selector sent to instance 0x712b130
I don't understand why I cannot access any objects in the passed dictionary.
我不明白为什么我不能访问传递的字典中的任何对象。
Thanks in advance for any help.
谢谢你的帮助。
John
约翰
3 个解决方案
#1
110
The first NSLog works fine displaying the contents of the dictionary. The second log throws the following exception...
第一个NSLog可以很好地显示字典的内容。第二个日志抛出以下异常…
The program tries to trick you, it just looks like it is your dictionary because your dictionary is inside the notification. From the exception you can see that your object actually is from a class named NSConcreteNotification.
This is because the argument of a notification-method is always a NSNotification-object. this will work:
程序试图欺骗你,它看起来就像你的字典,因为你的字典在通知里面。从这个异常中,您可以看到您的对象实际上来自一个名为nstenotification的类。这是因为notificationmethod的参数总是nsnotificationobject。这将工作:
- (void)hotSpotMore:(NSNotification *)notification {
NSLog(@"%@", notification.object);
NSLog(@"%@", [notification.object objectForKey:@"HelpTopic"]);
}
just as a hint: the object is usually the object which sends the notification, you should send your NSDictionary as userInfo.
I think it would improve your code if you would do it like this:
只是作为一个提示:发送通知的对象通常是对象,你应该把你的NSDictionary用户信息。我认为这将改善您的代码,如果你会这样做:
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center postNotificationName:@"HotSpotTouched" object:self userInfo:itemDetails];
- (void)hotSpotMore:(NSNotification *)notification {
NSLog(@"%@", notification.userInfo);
NSLog(@"%@", [notification.userInfo objectForKey:@"HelpTopic"]);
}
The object parameter is used to distinguish between the different objects that can send a notification.
Let’s say you have two different HotSpot objects that can both send the notification. When you set the object
in addObserver:selector:name:object:
you can add a different observer for each of the objects. Using nil as the object parameter means that all notifications should be received, regardless of the object that did send the notification.
对象参数用于区分可以发送通知的不同对象。假设您有两个不同的HotSpot对象,它们都可以发送通知。当您在addObserver:selector:name:object中设置对象时,您可以为每个对象添加不同的观察者。使用nil作为对象参数意味着应该接收所有通知,无论发送通知的对象是什么。
E.g:
例句:
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
}
#2
4
This is the best way to pass your dictionary data with NSNotification.
这是最好的方式与NSNotification通过你的字典数据。
Post Notification :
发布通知:
[[NSNotificationCenter defaultCenter] postNotificationName:@"Put Your Notification Name" object:self userInfo:"Pass your dictionary name"];
Add Observer for Handle the Notification.
为处理通知添加观察者。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mydictionaryData:) name:@"Put Your Notification Name" object:nil];
Put Notification Handler method.
把通知处理程序方法。
- (void)mydictionaryData::(NSNotification*)notification{
NSDictionary* userInfo = notification.userInfo;
NSLog (@"Successfully received test notification! %@", userInfo);}
I hope, this solution will help you
我希望这个解决方案能对你有所帮助
#3
3
The method Matthias is talking about and the one I think you should be using is
Matthias所说的方法我认为你们应该使用的方法是
postNotificationName:object:userInfo:
Where object is the sender and userInfo is your dictionary.
对象是发件人,userInfo是字典。
#1
110
The first NSLog works fine displaying the contents of the dictionary. The second log throws the following exception...
第一个NSLog可以很好地显示字典的内容。第二个日志抛出以下异常…
The program tries to trick you, it just looks like it is your dictionary because your dictionary is inside the notification. From the exception you can see that your object actually is from a class named NSConcreteNotification.
This is because the argument of a notification-method is always a NSNotification-object. this will work:
程序试图欺骗你,它看起来就像你的字典,因为你的字典在通知里面。从这个异常中,您可以看到您的对象实际上来自一个名为nstenotification的类。这是因为notificationmethod的参数总是nsnotificationobject。这将工作:
- (void)hotSpotMore:(NSNotification *)notification {
NSLog(@"%@", notification.object);
NSLog(@"%@", [notification.object objectForKey:@"HelpTopic"]);
}
just as a hint: the object is usually the object which sends the notification, you should send your NSDictionary as userInfo.
I think it would improve your code if you would do it like this:
只是作为一个提示:发送通知的对象通常是对象,你应该把你的NSDictionary用户信息。我认为这将改善您的代码,如果你会这样做:
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center postNotificationName:@"HotSpotTouched" object:self userInfo:itemDetails];
- (void)hotSpotMore:(NSNotification *)notification {
NSLog(@"%@", notification.userInfo);
NSLog(@"%@", [notification.userInfo objectForKey:@"HelpTopic"]);
}
The object parameter is used to distinguish between the different objects that can send a notification.
Let’s say you have two different HotSpot objects that can both send the notification. When you set the object
in addObserver:selector:name:object:
you can add a different observer for each of the objects. Using nil as the object parameter means that all notifications should be received, regardless of the object that did send the notification.
对象参数用于区分可以发送通知的不同对象。假设您有两个不同的HotSpot对象,它们都可以发送通知。当您在addObserver:selector:name:object中设置对象时,您可以为每个对象添加不同的观察者。使用nil作为对象参数意味着应该接收所有通知,无论发送通知的对象是什么。
E.g:
例句:
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
}
#2
4
This is the best way to pass your dictionary data with NSNotification.
这是最好的方式与NSNotification通过你的字典数据。
Post Notification :
发布通知:
[[NSNotificationCenter defaultCenter] postNotificationName:@"Put Your Notification Name" object:self userInfo:"Pass your dictionary name"];
Add Observer for Handle the Notification.
为处理通知添加观察者。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mydictionaryData:) name:@"Put Your Notification Name" object:nil];
Put Notification Handler method.
把通知处理程序方法。
- (void)mydictionaryData::(NSNotification*)notification{
NSDictionary* userInfo = notification.userInfo;
NSLog (@"Successfully received test notification! %@", userInfo);}
I hope, this solution will help you
我希望这个解决方案能对你有所帮助
#3
3
The method Matthias is talking about and the one I think you should be using is
Matthias所说的方法我认为你们应该使用的方法是
postNotificationName:object:userInfo:
Where object is the sender and userInfo is your dictionary.
对象是发件人,userInfo是字典。