This is something very fascinating I observed today. Maybe that's how Objective-C works but I didn't know about this. See the following code below:
// ATableViewController.h
@interface ATableViewController : UITableViewController
@end
// ATableViewController.m
@interface ATableViewController ()
@property (nonatomic) int volly;
@end
@implementation ATableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.volly = 5;
}
@end
// BTableViewController.h
@interface BTableViewController : ATableViewController
@end
// BTableViewController.m
@interface BTableViewController ()
@property (nonatomic) int volly;
@end
@implementation BTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"%d", self.volly); // returns 5
}
@end
I am not sure why the above is valid. I do understand that I passed a message 'volly' to the object 'self' which in turn probably looked at the value from the super class but shouldn't these be initialized? Some explanation would be of great help. Thanks.
EDIT: This is a big problem IMO though. Considering I don't know any of the private properties defined in the super class, my own set of values might end up being different.
For example, a developer may set a boolean flag hasAppeared
in viewDidAppear:
. This same value will be set for my subclass instance in viewDidAppear:
after the [super viewDidAppear:]
call. This will be before I actually get to set it myself.
Currently, the solution is I know exactly the variable used by the super class and I can avoid using the same value but I deem this to be a larger issue than it seems.
EDIT 2: The behavior is consistent with binaries (with only headers) as well as with frameworks where implementation is available.
I am answering this without reading all of the comments.
There is no issue here. Both AViewController
(AVC
) and BViewController
(BVC
) each have their own private property named volly
.
You created an instance of BVC
. It can't see the volly
property from its parent class (because it is private), just its own.
Now the fun begins.
The viewDidLoad
method from BVC
is called. It in turn calls [super viewDidLoad];
which of course calls the viewDidLoad
from the AVC
class. That method, in turn, calls self.volly = 5;
.
The confusion seems to be with this line. Remember, self.volly = 5;
is really a call to:
[self setVolly:5];
Both AVC
and BVC
have the (synthesized) setVolly:
method. Since self
is a pointer to an instance of a BVC
object, the call to [self setVolly:5];
results in a call to the setVolly:
method in the BVC
class despite being called from a method in the AVC
class.
Here's the code with some annotations:
The 'BVC' class:
- (void)viewDidLoad
{
[super viewDidLoad]; // calls the method in `AVC`
NSLog(@"%d", self.volly); // returns 5
}
The 'AVC' class:
- (void)viewDidLoad
{
[super viewDidLoad]; // calls the UITableViewController method
// The following is really [self setVolly:5];
// Since "self" is a "BVC", the private "volly" property of
// the "BVC" class is actually set here.
// The private "volly" property of the "AVC" class will still be
// 0 after this call.
self.volly = 5;
}
In the end, the subclass is not using the private property of the parent class. The original premise in the question's title is incorrect.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With