If I do nothing in -init, is it the same as just calling [MyClass alloc]?

孤者浪人 提交于 2019-12-09 15:36:30

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!