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*で、後で追加します...

とにかく、2つの間に大きな違いがあります。また、ハンドラーはバグがあります。そのコードを再検討する必要があります。

ブロックを好む理由はたくさんありますが、これはそのうちの1つを示しています。コードを登録に正しく入れるだけで、間違ったセレクターを指定する心配はありません。

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

これらはワンショット通知のように見えるため、通知ハンドラーを1回実行した後で登録を解除する場合は、これを実行します(に注意してください__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メソッドの1つだけが、「:」を使用して適切なセレクターを呼び出し、したがって適切なメソッドシグネチャを呼び出すことです。

于 2012-08-06T18:38:34.927 に答える