2

通知が投稿されたときに別のクラスにあるセレクターを呼び出す方法を知りたいです。私はタブバーコントローラーを使用しています。

FirstViewControllerタブバー項目SecondViewControllerです

Inside `FirstViewController` I have the following

-(void)viewdidload
{
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(productPurchased:)   name:kProductPurchasedNotification object:nil];

  [[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(productPurchaseFailed:) name:kProductPurchaseFailedNotification object: nil];

}

- (void)productPurchased:(NSNotification *)notification {

    [NSObject cancelPreviousPerformRequestsWithTarget:self];

    NSString *productIdentifier = (NSString *) notification.object;
    NSLog(@"Purchased: %@", productIdentifier);

    [appDelegate.myDownloadablePoemsArray addObject:productIdentifier];
    [self.tabBarController setSelectedIndex:3];
}

- (void)productPurchaseFailed:(NSNotification *)notification {

    [NSObject cancelPreviousPerformRequestsWithTarget:self];

    SKPaymentTransaction * transaction = (SKPaymentTransaction *) notification.object;    
    if (transaction.error.code != SKErrorPaymentCancelled) {    
        UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"Error!" 
                                                         message:transaction.error.localizedDescription 
                                                        delegate:nil 
                                               cancelButtonTitle:nil 
                                               otherButtonTitles:@"OK", nil] autorelease];

        [alert show];
    }

}

上記のコードは正常に動作しています。問題は何ですか、別のビューから同じセレクターメソッドを呼び出したいとします。たとえばSecondViewController、同じ通知オブザーバーを追加するという名前のビューコントローラーがあります。

ただし、セレクター メソッドは では呼び出されませんFirstViewController

内部SecondViewControllerには次のものがあります

-(void)viewdidload
{
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(productPurchased:)   name:kProductPurchasedNotification object:nil];

  [[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(productPurchaseFailed:) name:kProductPurchaseFailedNotification object: nil];

}

FirstViewControllerしかし、私は;からセレコール メソッドを呼び出したいです。

教えてください、それは可能ですか?そして、どうすればそれを行うことができますか?

どうもありがとう

4

2 に答える 2

1

のインスタンスにはメソッドがあるため、を のポインタに変更SecondViewControllerselfます。observerFirstViewControllerFirsViewController

SecondViewController.m内では、次の行を使用する必要があります。

- (void)viewdidload {
  [[NSNotificationCenter defaultCenter] addObserver:firstViewController selector:@selector(productPurchased:)   name:kProductPurchasedNotification object:nil];
  [[NSNotificationCenter defaultCenter] addObserver:firstViewController selector: @selector(productPurchaseFailed:) name:kProductPurchaseFailedNotification object: nil];
}

しかし!そしてこれがポイントです。

FirstViewController既に有効で、上記のメソッドを使用してメモリに読み込まれたビュー コントローラーであり、 でこれらの通知のオブザーバーである場合は、が受信できるため、NSNotificatioCenterに再度追加する必要はありません。それでも目的の通知を受け取ります。(他のView Controllerがカバーしているため、表示されていません。)NSNotificationCenterFirstViewController

FirstViewControllerが存在するときに が存在しない場合、が以前にインスタンス化されていなかっSecondViewControllerたため、別のクラスから呼び出されたインスタンス メソッドに到達できずFirstViewController、また に追加することもできませんNSNotificationCenter

結論

と の精神に従って、すべての独立したビュー コントローラーに使用できる第 3 のクラスに購入コールバックを分離することをお勧めしOOPますMVC

于 2012-08-18T07:46:43.377 に答える
0

ビュー コントローラーがタブ バー コントローラーのルートである場合、最初に読み込まれると、手動で置き換えない限り残ります。

したがって、最初のコントローラーに通知ハンドラーをインストールすると、通知ハンドラーを削除しない限り、2 番目のコントローラーが画面に表示されている場合でも通知ハンドラーは取得されます。

現在は、メモリ不足やカスタム タブ バー コントローラー コードによってアンロードされる可能性があります。ただし、タブ バー コントローラーがそのビュー コントローラーの 1 つを割り当て解除することは非常にまれであるため、インストールされた通知ハンドラーはキャンセルされるまで残ります。

実際、両方のView Controllerが通知を登録すると、両方とも通知を受け取ります。

viewDidLoad最初のコントローラーが読み込まれ、最初のコントローラーとして表示されるため、最初のコントローラーがすぐに登録されます。これらの通知は引き続き受信されます。

2 番目のものをロードすると、それも登録されます。これで、両方のビュー コントローラーが通知を受信して​​います。最初のView Controllerに戻ると、両方ともまだ通知を受け取っています。

于 2012-08-18T06:54:52.900 に答える