简体   繁体   中英

iOS strange delegate behavior?

I have a really strange delegate behavior in iOS. I'm setting a custom delegate in a subclassed UIViewController like this:

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.baseNavigationBar = [[BaseNavigationBar alloc] initWithNibName:nil bundle:nil];
    self.baseNavigationBar.delegate = self;
    self.baseNavigationBar.navigationController = self.navigationController;
    [self.navigationController.navigationBar addSubview:self.baseNavigationBar];
}

The initWithNibName can use nil, when using the default nib, because internally it will check fora nil in the nibName.

if (!nibNameOrNil) {
    nibNameOrNil = NSStringFromClass([self class]);
}

The delegate declaration from the baseNavigationBar object looks the following:

@property (nonatomic, retain) id<BaseNavigationBarDelegate> delegate;
/*same thing with assign, which I you should use*/
/*and in the .m of course @synthesize*/

And now 2 screenshots from the running application.

The first one show's the debugger values from the BaseListViewController , which is a subclass of BaseCoreViewController , which is a subclass of UIViewController .

The screenshot is taken, when the viewDidLoad method is called.

列表控制器

The second one show's the values from the BaseNavigationBar , which is a UIView subclass.

The screenshot is taken at a time, when the user clicks the "next" button

- (IBAction)nextAction:(id)sender {
    if (self.delegate) {
        [self.delegate navigationBarDidClickNextButton:self];
    }
}

导航栏

So why is this a problem? By clicking a button in the BaseNavigationBar my delegate is always nil, so the program is stuck. But when looking at the values from the BaseCoreViewController at the same time the delegate is not nil. Very strange.

Edit

The BaseNavigationBar is loaded from a nib file using the UINib loadNibNamed:owner:options: function.

Edit 2

So that's pretty much all of the code.

Edit 3

Finally we got the source of the error in the last pieces of the code... setting self = something totally not allowed...

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {

    if (!nibNameOrNil) {
        nibNameOrNil = NSStringFromClass([self class]);
    }

    if (!nibBundleOrNil) {
        nibBundleOrNil = [NSBundle mainBundle];
    }

    NSArray *topLevelObjects = [nibBundleOrNil loadNibNamed:nibNameOrNil owner:self options:nil];
    /*Here is the bad part*/
    self = [topLevelObjects objectAtIndex:0];

    state = BaseNavigationBarButtonStateNext;

    if (self) {
        self.title = @"";
    }
    return self;
}

Solved using a Class method instead of defining a custom init.

If you are using nib file, you should declare the nib class while initialising your class object.

You have initialised initWithNibName:nil

self.baseNavigationBar = [[BaseNavigationBar alloc] initWithNibName:nil bundle:nil];

but it should be like initWithNibName:@"BaseNavigationBar"

self.baseNavigationBar = [[BaseNavigationBar alloc] initWithNibName:@"BaseNavigationBar" bundle:nil]; 

Not sure what the problem is. Require some more code to analyze the problem. But what I can see is address of BaseNavigationBar in both the screen shots is different. It means the BaseNavigationBar object present in the controller is not the one which got the nextAction event as in second screen shot.

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