0
votes

For some reason I am experiencing an issue where, inside of a viewController's code (which runs well after the viewDidLoad method is called), self always returns nil. (Running on iPad Air with iOS 9.2.1, app built with 9.2 as the target).

In the initialization code we have a run-of-the-mill initter:

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

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) { }
    return self;
}

The viewController gets instantiated like this:

myVC * myVC = [[myVC alloc] initWithNibName:nil bundle:nil];

The names of the myVC class and .xib file are the same.

There's a property called:

@property (weak, nonatomic) IBOutlet UILabel *ipAddressLabel;

In a method inside myVC, I have a method like this:

- (void) networkPropertiesDidChange:(NSDictionary *)properties {
    void (^completionBlock)(UIAlertAction *) = ^(UIAlertAction *action) {
        [self.serialNumberField setEnabled:false];
    };
    if([properties[@"result" isEqualToString @"error"]) {
        [Utility showBasicAlertControllerWithText:@"Device not registered." completionBlock:completionBlock sender:self];
        return;
    }
    else if ([properties[@"result"] isEqualToString @"ipChange"]) {
        NSString *newAddy = [[NSString alloc] initWithString:properties[@"ipAddress"]];
        self.ipAddressLabel.text = newAddy;
        return;
    } 
    else return;
}

However the address label just goes blank.

When I step through the code while it executes, on the line where I initialize newAddy, self is not nil, and ipAddressLabel is not nil. However when the runtime hits self.ipAddressLabel.text, then it goes through initWithNibName, and returns nil for self! Then ipAddressLabel gets set to nil, and then it turns blank on the view.

At this point myVC has already successfully loaded and is on the screen. So I cannot understand why self is returning nil for self, inside this method... it's very odd.

If I delete my override of the initWithNibName method, then everything just works perfectly. If I check if (self != nil) at the beginning of initWithNib name before setting self=[super... ], then the view draws about 1" too low on the screen and gets cut off.

Just trying to understand why this was happening. Thanks.

1
Just some thoughts: 1) add a dealloc method with a NSLog, see if that gets called (and for some reason this object isn't retained) - 2) add your own customer setter for your ipAddressLabel, log when its set to something along with value (to see if its getting nil'd). Add asserts (or NSAsserts) all over your methods to test if ipAddressLabel is nil. - David H
Can't add dealloc, I'm using ARC. I tried adding the custom setter already, but can't call a method on a nil object. I added assertions and ipAddressLabel is not nil until I call self.ipAddressLabel.text = newAddy;... - CommaToast
Dealloc is still sent under arc - David H

1 Answers

0
votes

The problem is here:

void (^completionBlock)(UIAlertAction *) = ^(UIAlertAction *action) {
    [self.serialNumberField setEnabled:false];
};

It needs to be weakSelf...

    __weak typeof(self) weakSelf = self;
    void (^completionBlock)(UIAlertAction *) = ^(UIAlertAction *action) {
        [weakSelf.paxSerialNumberField setEnabled:false];
    };

Don't ask me why, my brain exploded.