问题
If I have an NSObject
subclass which either has no -init
method or simply does nothing in -init
, is there any difference between an instance created these two ways:
MyClass *instance = [MyClass alloc];
MyClass *instance = [[MyClass alloc] init];
By "does nothing in -init
" I mean
- (id)init {
self = [super init];
if (self) {
}
return self;
}
Since NSObject
's -init
method itself does nothing, I can't see there being any difference, but of course the advice is that you must call -init
to properly prepare an object.
Here's the snippet from NSObject's -init method which got me wondering about this:
The init method defined in the NSObject class does no initialization; it simply returns self.
回答1:
If I have an
NSObject
subclass which either has no-init
method or simply does nothing in-init
, is there any difference between an instance created these two ways:
MyClass *instance = [MyClass alloc];
MyClass *instance = [[MyClass alloc] init];
Technically, there is no difference.
But that doesn't mean you should use a bare +alloc
to ever create an instance for a variety of reasons.
First, it is the principal of the thing. Objective-C coding standards say +alloc
should always be followed by -init
.
Secondly, it is all about consistency and code maintenance. What happens when you refactor MyClass
to be a subclass of some class where the designated initializer is actually critical? A nasty, hard to figure out, bug is what happens.
Of relevance, note that the use of +new
has been all but deprecated for a similar reason. It makes refactoring tedious (dammit! gotta break apart THIS call site, too!) and the convenience factor is exceedingly minimal.
回答2:
No, it's not and you're not doing nothing, you're calling [super init]
and that does a lot to initialize your superclasses up until NSObject
.
回答3:
You can do it in theory.
When you want to create an instance, you can do it simply using the alloc
method, so this code is perfectly accepted:
NSObject *someObject = [NSObject alloc];
What creates the instance is the alloc
method, so you have created an instance of NSObject.
But if you want to use it you have to initialize it, since the NSObject init
method is used by a class to make sure its properties have suitable initial values at creation (Apple documentation).
The most important thing done by the init method is to create the self variable, so if you want to use the instance created with the alloc method, you have to init it.
- (id)init {
self = [super init];
if (self) {
// initialize instance variables here
}
return self;
}
Without the initialization method you have only an unusable instance.
回答4:
alloc
allocates a place in memory for the instance of the object to be stored. If you’re using a local variable it is allocated on the stack, while objects (ivars etc) are allocated on the heap.
init
initialises the instance of the object and points it to the allocated memory space - this is why you must always call init
after alloc
.
e.g.
MyClass *instance = [[MyClass alloc] init];
In your instance your init implementation is empty so it can be removed and you can let the superclass handle it. You would override init to set some state on the object itself.
You might want to take some time to read the Apple Documentation on this if you want to brush up.
回答5:
Calling MyClass *instance = [MyClass alloc];
- will leave you with an invalid object. You need to allocate
and initialize
every object you create.
If you do it this way, all objects until MYClass
will be initialised. MyClass
won't though.
来源:https://stackoverflow.com/questions/22662810/if-i-do-nothing-in-init-is-it-the-same-as-just-calling-myclass-alloc