【问题标题】:Call Selector method from another Class - NSNotificationCenter从另一个类调用 Selector 方法 - NSNotificationCenter
【发布时间】:2012-08-18 20:58:55
【问题描述】:

我想知道在发布通知时如何调用另一个类中的选择器。我在 tabbarcontroller 上。

FirstViewControllerSecondViewController标签栏项目

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调用selecor方法;

请告诉我,这可能吗?我该怎么做?

非常感谢

【问题讨论】:

  • 只有在 FirstViewController 处于活动状态时才有可能。
  • 所以请告诉我我该怎么做
  • 我没有SKPaymentTransaction 类的经验。我在我的项目中使用这个单例类:github.com/MugunthKumar/MKStoreKit

标签: iphone ios ios4 nsnotificationcenter


【解决方案1】:

SecondViewController中将self改成observerFirstViewController的指针,因为FirsViewController的实例有方法。

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 中这些通知的观察者,则不需要再次将其添加到NSNotificationCenter,因为FirstViewController 可以接收并且仍将接收所需的通知。 (它只是没有显示,因为另一个视图控制器覆盖了它。)

如果在SecondViewController 存在时FirstViewController 尚不存在,则您无法访问从另一个类调用的任何实例方法,因为FirstViewController 之前未实例化,并且您无法将其添加到NSNotificationCenter也是。

结论

根据OOPMVC 的精神,最好将购买回调隔离到可用于每个独立视图控制器的第三类中。

【讨论】:

    【解决方案2】:

    如果您的视图控制器是标签栏控制器的根,一旦它们第一次加载,除非手动替换,否则它们会一直存在。

    因此,当您在第一个控制器中安装通知处理程序时,除非您删除通知处理程序,否则即使第二个控制器在屏幕上,它仍然会获取它们。

    现在,由于内存压力或自定义标签栏控制器代码,它可能会被卸载。但是,标签栏控制器释放其视图控制器之一的情况非常罕见,因此您安装的通知处理程序将一直存在,直到您取消它们。

    事实上,如果两个视图控制器都注册了通知,那么它们都会得到通知。

    您正在viewDidLoad 中注册,因此第一个将立即注册,因为它将被加载并显示为初始控制器。它将继续接收这些通知。

    当第二个加载时,它也会注册。现在两个视图控制器都在接收通知。当您返回第一个视图控制器时,它们仍然会收到通知。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-07
      • 1970-01-01
      • 2011-09-09
      相关资源
      最近更新 更多