Custom Object Initialization in Objective-C
I created a custom object in Objective-C. Now I want to create a custom initializer. The object has two properties, name and score. 开发者_高级运维So my initializer is as follows:
- (id)initWithName:(NSString *)playerName {
if ((self = [super init])) {
self.name = [playerName retain];
self.score = [NSNumber numberWithInt:0];
}
return self;
}
Am I using retain
here properly? Or can I just make it something like self.name = playerName;
?
Furthermore, assume I want another initializer, but keep the initWithName:playerName
the designated initializer. How would I make the second initializer call the first?
And for the last question, I know I need to override the - (id)init
method too. However, what do I do there? Just assign test properties incase the class was initialized with init
only?
Thank you!
Am I using retain here properly?
No you are not. You should either use
self.name = playerName;
as you suggested, or (as recommended by Apple)
name = [playerName copy];
It is not recommended to use accessors in -init
because subclasses might override them.
Also, note that as NSString
implements NSCopying
you should use a copy property, not a retain property.
Furthermore, assume I want another initializer, but keep the initWithName:playerName the designated initializer. How would I make the second initializer call the first?
Using -init
as an example (because you must override the super class's designated initialiser if your designated initialiser is not the same)
-(id) init
{
return [self initWithName: @"Some default value"];
}
you could keep self.name = playerName;
if you have declared name
as retained property in .h class and have also @synthesized
in .m file.
For the initialization you could put the belwo two line of code in separate method.
-(void) initializeWithName:(NSString*) aName withNumber:(int) aNumber
{
self.name = aName;
self.score = [NSNumber numberWithInt:aNumber];
}
Lets you have three Initialization method.
- (id)initWithName:(NSString *)playerName {
if ((self = [super init])) {
[self initializeWithName:playerName withNumber:0]
}
return self;
}
- (id)initWithNumber:(int*) aNumber {
if ((self = [super init])) {
[self initializeWithName:nil withNumber:aNumber]
}
return self;
}
- (id)init{
if ((self = [super init])) {
[self initializeWithName:nil withNumber:0]
}
return self;
}
For what's it's worth to the rest of us newbies:
In normal languages, can simply define arguments when instantiating the class:
public final class MakeBed {
private var foo:Object;
public var bar:Array;
public function MakeBed(_foo:Object, _bar:Array) {
// Do stuff
foo = _foo;
bar = _bar;
}
}
Then when we want to instantiate the class it's as simple as:
var myBeadMaker:MakeBed = new MakeBed({}, []);
In objc everything is backasswards.
You can create your custom initializer similar to:
// These @properties go into the header.h file
@property (nonatomic, retain) NSString *foo;
@property (nonatomic, retain) NSString *bar;
// This is in your implimentation.m file
- (id) initWithInfo:(NSObject*)foo withBar:(NSArray *)bar {
_foo = foo;
_bar = bar;
}
Objc automatically "synthesizes" the getters and setters and automatically creates a new variable "blindly" using the same _name _but _with _an _underscore in front when you do the @property thing -- it's magic -- bordering on the "almost too helpful" side of things.
Handy for non-newbies, but incredibly confusing for newbies -- just believe that the getter and setter is made and that a _new _var _is _available.
And the clincher that everyone forgets to mention...
When you want to instantiate the class with your custom initializer you do this:
MakeBed myBedMaker = [[MakeBed alloc] initWithInfo:*foo withBar:*bar];
精彩评论