在UITabbarController中设置viewcontrollers的委托

时间:2013-06-03 15:04:46

标签: ios objective-c sdk uitabbarcontroller

我的应用程序中有以下设置:

带有3个viewcontrollers的UITabbarController,带有嵌入式UINavigationControllers。 来自UIViewController子类的3个viewcontrollers inheret / superclass称为“SVC”,以实现在所有3. viewcontrollers中使用的元素并防止重复的代码。在这个“SVC”类中,我设置了一个名为“dismissDelegate”的委托(用于告诉tabbarcontroller何时被调用)。

@protocol ModalViewDelegate <NSObject>

    - (void)didDismissModalViewFrom:(UIViewController *)viewController;

@end
   @property (weak, nonatomic) id <ModalViewDelegate> dismissDelegate;

我的另一个查看到UITabbarController的viewcontroller实现了这个委托,以便在tabbarcontroller被解除时获取有关的信息。

SVC类通知代表解除标签栏,如下所示:

 [self.dismissDelegate didDismissModalViewFrom:self]; 

我现在想要将SVC类(所有tabbar视图控制器)中的所有视图控制器的委托设置到此viewcontroller,我尝试通过prepareToSegue方法执行此操作,如下所示:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{

   if ([[segue identifier] isEqualToString:@"ToTab"]) {


        UITabBarController *tabBarController = segue.destinationViewController;

        for (UINavigationController *navController in  tabBarController.viewControllers) {


            for (UIViewController *vc in navController.viewControllers) {
                _SubclassVC = (SVC *) vc.superclass;
                _SubclassVC.dismissDelegate = self; 

            }

        }


    }

}

但是我收到以下错误:

+[SVC setDismissDelegate:]: unrecognized selector sent to class 0xbca68

我的问题:

  1. 这是解决这个问题的正确方法吗(获取有关解除视图控制器的信息,并在多个视图控制器固有的子类中设置此委托)?
  2. 如何设置我的第一个viewcontroller作为tabbar中所有viewcontrollers的委托 - SVC类,这样我可以在tabbarcontroller被告知时得到通知并解决错误?

1 个答案:

答案 0 :(得分:3)

+[SVC setDismissDelegate:]: unrecognized selector sent to class 0xbca68

请参阅 +

加号表示您正在调用类方法。您必须尝试通过setter设置类变量。但是属性仅表示实例变量。因此,自动生成的setter和getter仅为intance方法。 (在这样的错误消息中以减号 - 开头)。

这就是你所做的:

        _SubclassVC = (SVC *) vc.superclass;
        _SubclassVC.dismissDelegate = self;

无论出于何种原因(可能是由于错误或误解),您都会获取vc实例并获取其superclassvc.superclass返回一个类对象,而不是一个对象(意思不是一个实例,在Obj-C类对象中也是对象)。 然后你将其类型化为(SVC *)只是为了阻止编译器抛出错误(或警告 - 不确定)。

嗯,我猜你自己想知道为什么你必须根除它。这就是原因:)

接下来,您将self分配给属性dismissDelegate。编译器执行此操作是因为您将其类型化为具有属性dismissDelegate的SVC *。编译器实际上会像往常一样在这样的结构中调用setter setDismissDelegate

但是在运行时,消息(或选择器)setDismissDelegate:不会发送到SVC*,而是发送到class对象。类SVC没有方法(或选择器)+setDismissDelegate:,因此无法解析消息。而这正是错误消息告诉你的。

好的,现在我们回答你的问题。 嗯,这不是我想做的方式,但这肯定是实现它的一种方式。 2.如果你想坚持这种不寻常的方法,那么做这个小改动,你将摆脱错误:

for (SVC *vc in navController.viewControllers) {
    vc.dismissDelegate = self; 
}

获取超类对象没有意义。如果您无法访问超类的属性,那么您对继承链做错了。 如果你想要在保存方面:

for (UIViewController *vc in navController.viewControllers) {
  if (vc isKindOfClass:[SVC class]){  //BTW, this is good usage of the class object
    SVC *svc = (SVC*) vc;
    svc.dismissDelegate = self; 
  }
}