1

我正在开发一个系统来跟踪成就并为此使用NSNotificationCenter. 当应用程序中的对象解锁成就时,会发送通知JMAchievementHandler,将字符串设置为YES并将进度保存在NSUserDefaults. 我的问题是通知可能不起作用。这是我的代码JMAchievementHandler

- (id)init {
    self = [super init];
    if (self) {

        //Set strings to NO
        achievementOne = @"NO";
        achievementTwo = @"NO";
        achievementThree = @"NO";
        achievementFour = @"NO";

        //Add observers
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotificationWithName:) name:@"achievement1" object:nil];

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

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

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

        //Add observer to observe delegate methods
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNotificationFromDelegate:) name:@"notificationLaunch" object:nil];

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

    }
    return self;
}

- (void)receiveNotificationWithName:(NSNotification *)notification {
    if ([[notification name] isEqualToString:@"achievement1"] || [achievementOne isEqualToString:@"NO"]) {

        //unlock achievement
        NSLog(@"%@ is unlocked", [notification name]);
        achievementOne = @"YES";
    }

    else if ([[notification name] isEqualToString:@"achievement2"] || [achievementTwo isEqualToString:@"NO"]) {

        //unlock achievement
        NSLog(@"%@ is unlocked", [notification name]);
        achievementTwo = @"YES";
    }

    else if ([[notification name] isEqualToString:@"achievement3"] || [achievementThree isEqualToString:@"NO"]) {

        //unlock achievement
        NSLog(@"%@ is unlocked", [notification name]);
        achievementThree = @"YES";
    }

    else if ([[notification name] isEqualToString:@"achievement4"] || [achievementFour isEqualToString:@"NO"]) {

        //unlock achievement
        NSLog(@"%@ is unlocked", [notification name]);
        achievementFour = @"YES";
    }
}

- (void)receiveNotificationFromDelegate:(NSNotification *)notificationDelegate
{
    if ([[notificationDelegate name] isEqualToString:@"notificationLaunch"]) {

        [self loadDataOnLaunch];
    }
    else if ([[notificationDelegate name] isEqualToString:@"notificationEnterBackground"]) {
        [self saveDataOnExit];
    }
}

- (void)loadDataOnLaunch
{
    NSLog(@"loadDataOnLaunch");
}

- (void)saveDataOnExit
{
    NSLog(@"saveDataOnExit");
}

当我尝试发布通知时,不会调用 NSLog。我使用以下代码从我的AppDelegate和发送通知ViewController

- (void)achievement1ButtonPressed:(id)sender {

    [[NSNotificationCenter defaultCenter] postNotificationName:@"achievement1" object:self userInfo:nil];
}

我希望你们能帮助我。非常感谢

  • 乔纳斯
4

3 回答 3

3

你甚至有一个名为的方法receiveNotificationWithName吗?当您输入代码时,自动完成应该对此感到不满,receiveNotificationWithName:而是提供(除非您先编写它,没有NSNotification*,然后再添加它......

无论如何,两者之间有很大的不同。此外,您的处理程序有问题。您应该重新访问该代码。

有很多理由更喜欢块,这就是其中之一。您可以将您的代码正确地放入注册中,而不必担心提供错误的选择器。

[[NSNotificationCenter defaultCenter] addObserverForName:@"achievement1"
                                                  object:nil
                                                   queue:nil
                                              usingBlock:^{
    // Handle achievement1 right in this little block.
}];

这些看起来像一次性通知,因此如果您想在通知处理程序运行一次后取消注册,请执行此操作(注意__block)。

__block id achievement1 = [[NSNotificationCenter defaultCenter]
                              addObserverForName:@"achievement1 ":^{
                                          object:nil
                                           queue:nil
                                      usingBlock:^{
    // Handle achievement1 right in this little block.

    // Remove observer from notification center
    [[NSNotificationCenter defaultCenter] removeObserver:achievement1];
}];
于 2012-08-06T19:13:18.580 回答
1

所有这些看起来都应该起作用(除了冒号,就像 Andrea 提到的那样)。是否有可能因为类似的原因没有调用您的按钮回调?我会NSLog在您的achievement1ButtonPressed:方法中添加一个以确保。

于 2012-08-06T19:29:47.040 回答
0

我可以看到,您的addObesrver方法中只有一个使用“:”调用正确的选择器,因此是正确的方法签名。

于 2012-08-06T18:38:34.927 回答