使用NSNotifications发送无法识别的选择器

时间:2012-01-03 15:20:27

标签: objective-c xcode xcode4 xcode4.2

我在ViewController中使用NSNotifications,通过按下按钮来更新另一个ViewController中的UILabel:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
...
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateLabel:)
         name:@"LABELUPDATENOTIFICATION" object:nil];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"LABELUPDATENOTIFICATION" object:@"test"]; 
...

接收字符串的代码(@“test”):

- (void)updateLabel:(NSNotification*)notification
{
    NSString *updatedText = (NSString*)[notification object];
    [details setText:updatedText];
}

当我按下按钮(执行第一个代码时)和第二个按钮时,它给了我一个惊喜 代码高亮显示错误:“无法识别的选择器发送到实例”

感谢帮助我,我真的不明白通知......

第二个问题可能是如何发送第二个通知来更新同一控制器中的第二个UILabel ......

非常感谢!

修改: 这里是错误的痕迹:

2012-01-03 16:14:43.054 emars[3749:b303] -[ThirdViewController updateLabel:]: unrecognized selector sent to instance 0x685a0a0
2012-01-03 16:14:43.055 emars[3749:b303] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ThirdViewController updateLabel:]: unrecognized selector sent to instance 0x685a0a0'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x00fb45a9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x01108313 objc_exception_throw + 44
    2   CoreFoundation                      0x00fb60bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
    3   CoreFoundation                      0x00f25966 ___forwarding___ + 966
    4   CoreFoundation                      0x00f25522 _CF_forwarding_prep_0 + 50
...

编辑2:

NSDictionary *myDictionnary = [NSDictionary dictionaryWithObjectsAndKeys:@"details",@"details de l'installation",@"recapitulatif",@"recapitulatif de l'installe",nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateLabel:)
         name:@"LABELUPDATENOTIFICATION" object:nil];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"LABELUPDATENOTIFICATION" object:self userInfo:myDictionnary];

在另一个班级:

- (void)updateLabel:(NSNotification*)notification
{
    NSDictionary *dictionnary = (NSDictionary*)[notification object];
    [details setText:[dictionnary objectForKey:@"adetails"]];
    [recapitulatif setText:[dictionnary objectForKey:@"recapitulatif"]];
}

我有两个错误;一个可爱的SIGABRT和:

unrecognized selector sent to instance 0x683d630
2012-01-03 17:37:21.783 emars[6288:b303] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ThirdViewController updateLabel:]: unrecognized selector sent to instance 0x683d630'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x00fb45a9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x01108313 objc_exception_throw + 44
    2   CoreFoundation                      0x00fb60bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
    3   CoreFoundation                      0x00f25966 ___forwarding___ + 966
...

感谢您的帮助!!!

2 个答案:

答案 0 :(得分:3)

您正在错误地使用发布通知方法。 object:参数是发布通知的对象。您已将该对象指定为@"test"。此字符串对象不应发布任何通知。你需要做的是

[[NSNotificationCenter defaultCenter] postNotificationName:@"LABELUPDATENOTIFICATION" object:self userInfo:aDictionary];

userInfo应为NSDictionary,并且是您通过通知传递对象的方式。您可以使用相同的通知传递两个标签的文本。只需使用字符串构造字典。

aDictionary=[NSDictionary dictionaryWithObjectsAndKeys:@"test1",@"label1",@"test2",@"label2",nil];

修改 是的,您似乎仍然对通知的工作方式存在误解。假设您有两个视图控制器VC1和VC2。如果VC1将发布带有标签值(通知在VC2中)的通知,则它不应该是观察者。你已经正确发布了它但声明

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

不应该在VC1中。或者更确切地说,正如@dean Wombourne所说,你应该添加另一个视图控制器(VC2)作为观察者。崩溃的原因是您将VC1添加为观察者,并且它没有实现updateLabel:。我猜你不会有VC2对象的参考。因此,只需将添加观察者代码剪切并粘贴到VC2的viewDidLoad中。

答案 1 :(得分:1)

错误跟踪表明对象ThirdViewController已收到选择器updateLabel:

你问题中的updateLabel:方法看起来还不错,但我打赌它在错误的课程中:)

请改为尝试:

[[NSNotificationCenter defaultCenter] addObserver:otherViewController selector:@selector(updateLabel:) name:@"LABELUPDATENOTIFICATION" object:nil];

在您的问题中,您要求将通知发送至self,而updateLabel:方法没有{{1}}。您需要通知中心哪个对象想要接收通知。