0

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

一个带有 3 个视图控制器的 UITabbarController,嵌入了 UINavigationControllers。这 3 个视图控制器从称为“SVC”的 UIViewController 子类继承/超类,以实现在所有 3.视图控制器中使用的元素并防止重复代码。在这个“SVC”类中,我设置了一个名为“dismissDelegate”的委托(用于判断 tabbarcontroller 何时被关闭)。

@protocol ModalViewDelegate <NSObject>

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

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

我的另一个与 UITabbarController 连接的视图控制器实现了这个委托,以便获取有关何时关闭 tabbarcontroller 的信息。

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

 [self.dismissDelegate didDismissModalViewFrom:self]; 

我现在想将所有从 SVC 类(所有选项卡视图控制器)继承的视图控制器的委托设置为这个视图控制器,我尝试通过 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. 我如何设法将我的第一个视图控制器设置为选项卡栏中所有视图控制器的代表 - SVC 类,以便在关闭选项卡控制器时收到通知并解决错误?
4

1 回答 1

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

+

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

这就是你所做的:

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

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

好吧,我猜你想知道为什么你必须对它进行类型转换。这就是原因:)

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

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

好的,现在我们来回答你的问题。1. 嗯,这不是我会做的方式,但这肯定是实现它的一种方式。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; 
  }
}
于 2013-06-03T15:31:04.930 回答