分配和初始化他们实际做了什么

den*_*iss 26 objective-c

有人可以向我解释一下init和alloc在Obj-C中做了什么.我正在阅读这本obj-c书,它提供了一个创建对象的例子,但它并没有详细说明它的作用.alloc返回什么?什么是init返回?

Animal * k = [Animal alloc];
k = [k init];
Run Code Online (Sandbox Code Playgroud)

Yuj*_*uji 43

  • alloc 分配一块内存来保存对象,并返回指针.

    MyClass* myObj = [MyClass alloc];
    
    Run Code Online (Sandbox Code Playgroud)

    myObj尚未使用,因为其内部状态未正确设置.所以,不要写这样的代码.

  • init设置对象的初始条件并返回它.请注意,返回的内容 [a init] 可能与之不同a.这解释了Yannick写的代码:

    -init{
         self=[super init]; // 1.
         if(self){          // 2.
             ....
         }
         return self;       // 3.
    }
    
    Run Code Online (Sandbox Code Playgroud)
    1. 首先,你需要调用超类init,设置超类的实例变量等.这可能会返回不同于原始的东西self,所以你需要分配返回的内容self.
    2. 如果self是非零,则表示由超类控制的部分被正确初始化.现在,您执行初始化.所有实例变量都设置为nil(如果是对象),0如果是整数.您需要执行其他初始设置.
    3. 返回设置self.返回的self可能与分配的不同!因此,您需要将结果分配init给您的变量.

这个建议是一个重要的教训:永远不要将呼叫拆分为allocinit.不要写:

 MyClass* myObj = [MyClass alloc];
 [myObj init];
Run Code Online (Sandbox Code Playgroud)

因为[myObj init]可能会返回别的东西.不要试图通过写作来解决这个问题:

 MyClass* myObj = [MyClass alloc];
 myObj=[myObj init];
Run Code Online (Sandbox Code Playgroud)

因为你最终会忘记myObj=在第二行写下这个部分.

总是写:

 MyClass* myObj = [[MyClass alloc] init];
Run Code Online (Sandbox Code Playgroud)

我也不建议写:

 MyClass* myObj = [MyClass new];
Run Code Online (Sandbox Code Playgroud)

因为它没有正确调用初始化方法:某些类不接受普通方法init.例如,NSView需求initWithFrame:,无法调用new.所以,不要使用new任何一种.

  • 话虽这么说,如果你不需要自定义`-init`,你可以肯定地称为'+ new`.如果你看一下`+(id)new`的实现,它实际上就是`return [[self alloc] init];` (2认同)