简体   繁体   中英

Set delegate of viewcontrollers in UITabbarController

I have the following setup in my app:

A UITabbarController with 3 viewcontrollers, with embeded UINavigationControllers. The 3 viewcontrollers inheret/superclass from a UIViewController subclass called "SVC", in order to implement elements which is used in all of the 3. viewcontrollers and prevent duplicated code. In this "SVC" class I have setup a delegate called "dismissDelegate" (which is used to tell when the tabbarcontroller is dimissed).

@protocol ModalViewDelegate <NSObject>

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

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

My other viewcontroller which segues to the UITabbarController, implements this delegate in order to get information about, when the tabbarcontroller is dismissed.

the SVC class notifies the delegate of dismissal of the tabbar like so:

 [self.dismissDelegate didDismissModalViewFrom:self]; 

I now want to set the delegate of all the viewcontrollers which inherts from the SVC class (all the tabbar viewcontrollers) to this viewcontroller and I try to do this via the prepareToSegue method like so:

- (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; 

            }

        }


    }

}

But I get the following error:

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

My questions:

  1. Is this the right way to tackle this senario (get information about dismissal of a viewcontroller and setup this delegate in a subclass which is inhereted by multiple viewcontrollers)?
  2. How do I manage to set my first viewcontroller as the delegate of all the viewcontrollers in the tabbar - the SVC class, so I can get notified when the tabbarcontroller is dimissed and solve the error?
+[SVC setDismissDelegate:]: unrecognized selector sent to class 0xbca68

See the +

The plus sign idicates that you are calling a class method. You must have tried setting a class variable by a setter. But a property represents instance variables only. Therefore the setters and getters that are automatically generated are intance methods only. (starting with a minus - in error messages like this).

And that is what you do:

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

For whatever reason (probably by mistake or misunderstanding) you take the vc instance and get its superclass . vc.superclass returns a class object, not an object (meaning not an instance, in Obj-C class objects are objects too). Then you typecast it to (SVC *) just to stop the compiler from throwing errors (or warnings - not sure).

Well, I guess that you wondered yourself why you have to typecast it at all. That's the reason :)

Next, you assign self to a property dismissDelegate . The compiler does that because you typecasted it to SVC* which does have a property dismissDelegate . The compiler will actually call the setter setDismissDelegate as usual in contructs like this.

BUT at runtime the message (or selector) setDismissDelegate: is not sent to an SVC* but to a class object. And the class SVC does not have a method (or selector) +setDismissDelegate: and therefore cannot resolve the message. And that is exactly what the error message is telling you.

All right, now we get to your questions. 1. Well, it is not the way I would do it, but that is certainly one way of achiving it. 2. If you want to stick with that unusual approach then do this minor change and you will get rid of the error:

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

There is no point in fetching the superclass object. If you cannot access the property of a superclass then you did something wrong with the inheritance chain. If you want to be on the save side:

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; 
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM