I always see people debating whether or not to use a property's setter in the -init
method. My problem is how to create a default value in a subclass for an inherited property. Say we have a class called NSLawyer
-- a framework class, that I can't change -- with an interface that looks like this:
@interface NSLawyer : NSObject {
@private
NSUInteger _numberOfClients;
}
@property (nonatomic, assign) NSUInteger numberOfClients;
@end
And an implementation that looks like this:
@implementation NSLawyer
- (instancetype)init
{
self = [super init];
if (self) {
_numberOfClients = 0;
}
return self;
}
@end
Now let's say I want to extend NSLawyer
. My subclass will be called SeniorPartner
. And since a senior partner should have lots of clients, when SeniorPartner
gets initialized, I don't want the instance to start with 0
; I want it to have 10
. Here's SeniorPartner.m:
@implementation SeniorPartner
- (instancetype)init
{
self = [super init];
if (self) {
// Attempting to set the ivar directly will result in the compiler saying,
// "Instance variable _numberOfClients is private."
// _numberOfClients = 10; <- Can't do this.
// Thus, the only way to set it is with the mutator:
self.numberOfClients = 10;
// Or: [self setNumberOfClients:10];
}
return self;
}
@end
So what's a Objective-C newcomer to do? Well, I mean, there's only one thing I can do, and that's set the property. Unless there's something I'm missing. Any ideas, suggestions, tips, or tricks?
You should do exactly has you have; call the accessor. The declaring class typically avoids calling its own accessors in init
to avoid accidentally calling an overridden accessor in a subclass that might rely on the consistency of data you haven't initialized yet. Your superclass on the other hand should be completely consistent by the time the subclass's init
is run, so there is no problem using superclass accessors at that time.
Consider the common and general case: you want to set your transform
in a UIView
subclass. How would you solve that other than call setTransform:
? Subclassing non-Apple code is no different.